1- /* $OpenBSD: ca.c,v 1.3 2013/11/21 08:36:51 eric Exp $ */
1+ /* $OpenBSD: ca.c,v 1.4 2014/04/29 19:13:13 reyk Exp $ */
22
33/*
4+ * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org>
45 * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
56 *
67 * Permission to use, copy, modify, and distribute this software for any
1718 */
1819
1920#include <sys/types.h>
21+ #include <sys/queue.h>
22+ #include <sys/socket.h>
2023
21- #include <openssl/err.h>
22- #include <openssl/ssl.h>
24+ #include <string.h>
25+ #include <stdlib.h>
26+ #include <imsg.h>
2327
28+ #include <openssl/pem.h>
29+ #include <openssl/evp.h>
30+ #include <openssl/rsa.h>
31+ #include <openssl/engine.h>
32+
33+ #include "smtpd.h"
2434#include "log.h"
35+ #include "ssl.h"
36+
37+ static int ca_verify_cb (int , X509_STORE_CTX * );
38+
39+ static int rsae_send_imsg (int , const u_char * , u_char * , RSA * ,
40+ int , u_int );
41+ static int rsae_pub_enc (int , const u_char * , u_char * , RSA * , int );
42+ static int rsae_pub_dec (int ,const u_char * , u_char * , RSA * , int );
43+ static int rsae_priv_enc (int , const u_char * , u_char * , RSA * , int );
44+ static int rsae_priv_dec (int , const u_char * , u_char * , RSA * , int );
45+ static int rsae_mod_exp (BIGNUM * , const BIGNUM * , RSA * , BN_CTX * );
46+ static int rsae_bn_mod_exp (BIGNUM * , const BIGNUM * , const BIGNUM * ,
47+ const BIGNUM * , BN_CTX * , BN_MONT_CTX * );
48+ static int rsae_init (RSA * );
49+ static int rsae_finish (RSA * );
50+ static int rsae_sign (int , const u_char * , u_int , u_char * , u_int * ,
51+ const RSA * );
52+ static int rsae_verify (int dtype , const u_char * m , u_int , const u_char * ,
53+ u_int , const RSA * );
54+ static int rsae_keygen (RSA * , int , BIGNUM * , BN_GENCB * );
55+
56+ void
57+ ca_init (void )
58+ {
59+ BIO * in = NULL ;
60+ EVP_PKEY * pkey = NULL ;
61+ struct pki * pki ;
62+ const char * k ;
63+ void * iter_dict ;
64+
65+ log_debug ("debug: init private ssl-tree" );
66+ iter_dict = NULL ;
67+ while (dict_iter (env -> sc_pki_dict , & iter_dict , & k , (void * * )& pki )) {
68+ if (pki -> pki_key == NULL )
69+ continue ;
70+
71+ if ((in = BIO_new_mem_buf (pki -> pki_key ,
72+ pki -> pki_key_len )) == NULL )
73+ fatalx ("ca_launch: key" );
2574
26- int ca_X509_verify (X509 * , STACK_OF (X509 ) * , const char * , const char * , const char * * );
75+ if ((pkey = PEM_read_bio_PrivateKey (in ,
76+ NULL , NULL , NULL )) == NULL )
77+ fatalx ("ca_launch: PEM" );
78+ BIO_free (in );
79+
80+ pki -> pki_pkey = pkey ;
81+
82+ explicit_bzero (pki -> pki_key , pki -> pki_key_len );
83+ free (pki -> pki_key );
84+ pki -> pki_key = NULL ;
85+ }
86+ }
2787
2888static int
29- verify_cb (int ok , X509_STORE_CTX * ctx )
89+ ca_verify_cb (int ok , X509_STORE_CTX * ctx )
3090{
3191 switch (X509_STORE_CTX_get_error (ctx )) {
3292 case X509_V_OK :
@@ -50,7 +110,7 @@ verify_cb(int ok, X509_STORE_CTX *ctx)
50110}
51111
52112int
53- ca_X509_verify (X509 * certificate , STACK_OF ( X509 ) * chain , const char * CAfile ,
113+ ca_X509_verify (void * certificate , void * chain , const char * CAfile ,
54114 const char * CRLfile , const char * * errstr )
55115{
56116 X509_STORE * store = NULL ;
@@ -72,7 +132,7 @@ ca_X509_verify(X509 *certificate, STACK_OF(X509) *chain, const char *CAfile,
72132 if (X509_STORE_CTX_init (xsc , store , certificate , chain ) != 1 )
73133 goto end ;
74134
75- X509_STORE_CTX_set_verify_cb (xsc , verify_cb );
135+ X509_STORE_CTX_set_verify_cb (xsc , ca_verify_cb );
76136
77137 ret = X509_verify_cert (xsc );
78138
@@ -92,3 +152,262 @@ ca_X509_verify(X509 *certificate, STACK_OF(X509) *chain, const char *CAfile,
92152
93153 return ret > 0 ? 1 : 0 ;
94154}
155+
156+ void
157+ ca_imsg (struct mproc * p , struct imsg * imsg )
158+ {
159+ RSA * rsa ;
160+ const void * from = NULL ;
161+ u_char * to = NULL ;
162+ struct msg m ;
163+ const char * pkiname ;
164+ size_t flen , tlen , padding ;
165+ struct pki * pki ;
166+ int ret = 0 ;
167+
168+ m_msg (& m , imsg );
169+ m_get_string (& m , & pkiname );
170+ m_get_data (& m , & from , & flen );
171+ m_get_size (& m , & tlen );
172+ m_get_size (& m , & padding );
173+ m_end (& m );
174+
175+ pki = dict_get (env -> sc_pki_dict , pkiname );
176+ if (pki == NULL || pki -> pki_pkey == NULL ||
177+ (rsa = EVP_PKEY_get1_RSA (pki -> pki_pkey )) == NULL )
178+ fatalx ("ca_imsg: invalid pki" );
179+
180+ if ((to = calloc (1 , tlen )) == NULL )
181+ fatalx ("ca_imsg: calloc" );
182+
183+ switch (imsg -> hdr .type ) {
184+ case IMSG_CA_PRIVENC :
185+ ret = RSA_private_encrypt (flen , from , to , rsa ,
186+ padding );
187+ break ;
188+ case IMSG_CA_PRIVDEC :
189+ ret = RSA_private_decrypt (flen , from , to , rsa ,
190+ padding );
191+ break ;
192+ }
193+
194+ m_create (p , imsg -> hdr .type , 0 , 0 , -1 );
195+ m_add_int (p , ret );
196+ if (ret > 0 )
197+ m_add_data (p , to , (size_t )ret );
198+ m_close (p );
199+
200+ free (to );
201+ RSA_free (rsa );
202+ }
203+
204+ /*
205+ * RSA privsep engine (called from unprivileged processes)
206+ */
207+
208+ const RSA_METHOD * rsa_default = NULL ;
209+
210+ static RSA_METHOD rsae_method = {
211+ "RSA privsep engine" ,
212+ rsae_pub_enc ,
213+ rsae_pub_dec ,
214+ rsae_priv_enc ,
215+ rsae_priv_dec ,
216+ rsae_mod_exp ,
217+ rsae_bn_mod_exp ,
218+ rsae_init ,
219+ rsae_finish ,
220+ 0 ,
221+ NULL ,
222+ rsae_sign ,
223+ rsae_verify ,
224+ rsae_keygen
225+ };
226+
227+ static int
228+ rsae_send_imsg (int flen , const u_char * from , u_char * to , RSA * rsa ,
229+ int padding , u_int cmd )
230+ {
231+ int ret = 0 ;
232+ struct imsgbuf * ibuf ;
233+ struct imsg imsg ;
234+ int n , done = 0 ;
235+ const void * toptr ;
236+ char * pkiname ;
237+ size_t tlen ;
238+ struct msg m ;
239+
240+ if ((pkiname = RSA_get_ex_data (rsa , 0 )) == NULL )
241+ return (0 );
242+
243+ /*
244+ * Send a synchronous imsg because we cannot defer the RSA
245+ * operation in OpenSSL's engine layer.
246+ */
247+ m_create (p_lka , cmd , 0 , 0 , -1 );
248+ m_add_string (p_lka , pkiname );
249+ m_add_data (p_lka , (const void * )from , (size_t )flen );
250+ m_add_size (p_lka , (size_t )RSA_size (rsa ));
251+ m_add_size (p_lka , (size_t )padding );
252+ m_flush (p_lka );
253+
254+ ibuf = & p_lka -> imsgbuf ;
255+
256+ while (!done ) {
257+ if ((n = imsg_read (ibuf )) == -1 )
258+ fatalx ("imsg_read" );
259+ if (n == 0 )
260+ fatalx ("pipe closed" );
261+
262+ while (!done ) {
263+ if ((n = imsg_get (ibuf , & imsg )) == -1 )
264+ fatalx ("imsg_get error" );
265+ if (n == 0 )
266+ break ;
267+ if (imsg .hdr .type != cmd )
268+ fatalx ("invalid response" );
269+
270+ m_msg (& m , & imsg );
271+ m_get_int (& m , & ret );
272+ if (ret > 0 )
273+ m_get_data (& m , & toptr , & tlen );
274+ m_end (& m );
275+
276+ if (ret > 0 )
277+ memcpy (to , toptr , tlen );
278+ done = 1 ;
279+
280+ imsg_free (& imsg );
281+ }
282+ }
283+ mproc_event_add (p_lka );
284+
285+ return (ret );
286+ }
287+
288+ static int
289+ rsae_pub_enc (int flen ,const u_char * from , u_char * to , RSA * rsa ,int padding )
290+ {
291+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
292+ return (rsa_default -> rsa_pub_enc (flen , from , to , rsa , padding ));
293+ }
294+
295+ static int
296+ rsae_pub_dec (int flen ,const u_char * from , u_char * to , RSA * rsa ,int padding )
297+ {
298+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
299+ return (rsa_default -> rsa_pub_dec (flen , from , to , rsa , padding ));
300+ }
301+
302+ static int
303+ rsae_priv_enc (int flen , const u_char * from , u_char * to , RSA * rsa , int padding )
304+ {
305+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
306+ if (RSA_get_ex_data (rsa , 0 ) != NULL ) {
307+ return (rsae_send_imsg (flen , from , to , rsa , padding ,
308+ IMSG_CA_PRIVENC ));
309+ }
310+ return (rsa_default -> rsa_priv_enc (flen , from , to , rsa , padding ));
311+ }
312+
313+ static int
314+ rsae_priv_dec (int flen , const u_char * from , u_char * to , RSA * rsa , int padding )
315+ {
316+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
317+ if (RSA_get_ex_data (rsa , 0 ) != NULL ) {
318+ return (rsae_send_imsg (flen , from , to , rsa , padding ,
319+ IMSG_CA_PRIVDEC ));
320+ }
321+ return (rsa_default -> rsa_priv_dec (flen , from , to , rsa , padding ));
322+ }
323+
324+ static int
325+ rsae_mod_exp (BIGNUM * r0 , const BIGNUM * I , RSA * rsa , BN_CTX * ctx )
326+ {
327+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
328+ return (rsa_default -> rsa_mod_exp (r0 , I , rsa , ctx ));
329+ }
330+
331+ static int
332+ rsae_bn_mod_exp (BIGNUM * r , const BIGNUM * a , const BIGNUM * p ,
333+ const BIGNUM * m , BN_CTX * ctx , BN_MONT_CTX * m_ctx )
334+ {
335+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
336+ return (rsa_default -> bn_mod_exp (r , a , p , m , ctx , m_ctx ));
337+ }
338+
339+ static int
340+ rsae_init (RSA * rsa )
341+ {
342+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
343+ if (rsa_default -> init == NULL )
344+ return (1 );
345+ return (rsa_default -> init (rsa ));
346+ }
347+
348+ static int
349+ rsae_finish (RSA * rsa )
350+ {
351+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
352+ if (rsa_default -> finish == NULL )
353+ return (1 );
354+ return (rsa_default -> finish (rsa ));
355+ }
356+
357+ static int
358+ rsae_sign (int type , const u_char * m , u_int m_length , u_char * sigret ,
359+ u_int * siglen , const RSA * rsa )
360+ {
361+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
362+ return (rsa_default -> rsa_sign (type , m , m_length ,
363+ sigret , siglen , rsa ));
364+ }
365+
366+ static int
367+ rsae_verify (int dtype , const u_char * m , u_int m_length , const u_char * sigbuf ,
368+ u_int siglen , const RSA * rsa )
369+ {
370+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
371+ return (rsa_default -> rsa_verify (dtype , m , m_length ,
372+ sigbuf , siglen , rsa ));
373+ }
374+
375+ static int
376+ rsae_keygen (RSA * rsa , int bits , BIGNUM * e , BN_GENCB * cb )
377+ {
378+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
379+ return (rsa_default -> rsa_keygen (rsa , bits , e , cb ));
380+ }
381+
382+ int
383+ ca_engine_init (void )
384+ {
385+ ENGINE * e ;
386+
387+ log_debug ("debug: %s: %s" , proc_name (smtpd_process ), __func__ );
388+
389+ if ((e = ENGINE_get_default_RSA ()) == NULL ||
390+ (rsa_default = ENGINE_get_RSA (e )) == NULL )
391+ return (-1 );
392+
393+ if (rsa_default -> flags & RSA_FLAG_SIGN_VER )
394+ fatalx ("unsupported RSA engine" );
395+
396+ if (rsa_default -> rsa_mod_exp == NULL )
397+ rsae_method .rsa_mod_exp = NULL ;
398+ if (rsa_default -> rsa_mod_exp == NULL )
399+ rsae_method .rsa_mod_exp = NULL ;
400+ if (rsa_default -> bn_mod_exp == NULL )
401+ rsae_method .bn_mod_exp = NULL ;
402+ if (rsa_default -> rsa_keygen == NULL )
403+ rsae_method .rsa_keygen = NULL ;
404+ rsae_method .flags = rsa_default -> flags |
405+ RSA_METHOD_FLAG_NO_CHECK ;
406+ rsae_method .app_data = rsa_default -> app_data ;
407+
408+ if (!ENGINE_set_RSA (e , & rsae_method ) ||
409+ !ENGINE_set_default_RSA (e ))
410+ return (-1 );
411+
412+ return (0 );
413+ }
0 commit comments