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