xref: /netbsd-src/external/ibm-public/postfix/dist/src/tls/tls_rsa.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /*	$NetBSD: tls_rsa.c,v 1.1.1.2 2014/07/06 19:27:54 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	tls_rsa
6 /* SUMMARY
7 /*	RSA support
8 /* SYNOPSIS
9 /*	#define TLS_INTERNAL
10 /*	#include <tls.h>
11 /*
12 /*	RSA	*tls_tmp_rsa_cb(ssl, export, keylength)
13 /*	SSL	*ssl; /* unused */
14 /*	int	export;
15 /*	int	keylength;
16 /* DESCRIPTION
17 /*	tls_tmp_rsa_cb() is a call-back routine for the
18 /*	SSL_CTX_set_tmp_rsa_callback() function.
19 /*
20 /*	This implementation will generate only 512-bit ephemeral
21 /*	RSA keys for export ciphersuites. It will log a warning in
22 /*	all other usage contexts.
23 /* LICENSE
24 /* .ad
25 /* .fi
26 /*	This software is free. You can do with it whatever you want.
27 /*	The original author kindly requests that you acknowledge
28 /*	the use of his software.
29 /* AUTHOR(S)
30 /*	Originally written by:
31 /*	Lutz Jaenicke
32 /*	BTU Cottbus
33 /*	Allgemeine Elektrotechnik
34 /*	Universitaetsplatz 3-4
35 /*	D-03044 Cottbus, Germany
36 /*
37 /*	Updated by:
38 /*	Wietse Venema
39 /*	IBM T.J. Watson Research
40 /*	P.O. Box 704
41 /*	Yorktown Heights, NY 10598, USA
42 /*
43 /*	Viktor Dukhovni.
44 /*--*/
45 
46 /* System library. */
47 
48 #include <sys_defs.h>
49 #include <msg.h>
50 
51 #ifdef USE_TLS
52 
53 /* TLS library. */
54 
55 #define TLS_INTERNAL
56 #include <tls.h>
57 
58 /* tls_tmp_rsa_cb - call-back to generate ephemeral RSA key */
59 
60 RSA    *tls_tmp_rsa_cb(SSL *unused_ssl, int export, int keylength)
61 {
62     static RSA *rsa_tmp;
63 
64     /*
65      * We generate ephemeral RSA keys only for export ciphersuites.  In all
66      * other contexts use of ephemeral RSA keys violates the SSL/TLS
67      * protocol, and only takes place when applications ask for trouble and
68      * set the SSL_OP_EPHEMERAL_RSA option.  Postfix should never do that.
69      */
70     if (!export || keylength != 512) {
71 	msg_warn("%sexport %d-bit ephemeral RSA key requested",
72 		 export ? "" : "non-", keylength);
73 	return 0;
74     }
75 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
76     if (rsa_tmp == 0) {
77 	BIGNUM *e = BN_new();
78 
79 	if (e != 0 && BN_set_word(e, RSA_F4) && (rsa_tmp = RSA_new()) != 0)
80 	    if (!RSA_generate_key_ex(rsa_tmp, keylength, e, 0)) {
81 		RSA_free(rsa_tmp);
82 		rsa_tmp = 0;
83 	    }
84 	if (e)
85 	    BN_free(e);
86     }
87 #else
88     if (rsa_tmp == 0)
89 	rsa_tmp = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
90 #endif
91 
92     return (rsa_tmp);
93 }
94 
95 #ifdef TEST
96 
97 #include <msg_vstream.h>
98 
99 int     main(int unused_argc, char *const argv[])
100 {
101     RSA    *rsa;
102     int     ok;
103 
104     msg_vstream_init(argv[0], VSTREAM_ERR);
105 
106     /* Export at 512-bits should work */
107     rsa = tls_tmp_rsa_cb(0, 1, 512);
108     ok = rsa != 0 && RSA_size(rsa) == 512 / 8;
109     ok = ok && PEM_write_RSAPrivateKey(stdout, rsa, 0, 0, 0, 0, 0);
110     tls_print_errors();
111 
112     /* Non-export or unexpected bit length should fail */
113     ok = ok && tls_tmp_rsa_cb(0, 0, 512) == 0;
114     ok = ok && tls_tmp_rsa_cb(0, 1, 1024) == 0;
115 
116     return ok ? 0 : 1;
117 }
118 
119 #endif
120 
121 #endif
122