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