- Replace direct access to internals of openssl structs
by corresponding methods.
v2: Remove the call to EVP_PKEY_id() as its slated for removal
from the compat layer (see also review by Stefan)
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <1515956662-30572-1-git-send-email-selva.nair@gmail.com>
URL: https://www.mail-archive.com/search?l=mid&q=1515956662-30572-1-git-send-email-selva.nair@gmail.com
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -47,6 +47,7 @@ |
47 | 47 |
#include <assert.h> |
48 | 48 |
|
49 | 49 |
#include "buffer.h" |
50 |
+#include "openssl_compat.h" |
|
50 | 51 |
|
51 | 52 |
/* MinGW w32api 3.17 is still incomplete when it comes to CryptoAPI while |
52 | 53 |
* MinGW32-w64 defines all macros used. This is a hack around that problem. |
... | ... |
@@ -213,20 +214,20 @@ rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, in |
213 | 213 |
static int |
214 | 214 |
rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) |
215 | 215 |
{ |
216 |
- CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data; |
|
216 |
+ CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(RSA_get_method(rsa)); |
|
217 | 217 |
HCRYPTHASH hash; |
218 | 218 |
DWORD hash_size, len, i; |
219 | 219 |
unsigned char *buf; |
220 | 220 |
|
221 | 221 |
if (cd == NULL) |
222 | 222 |
{ |
223 |
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); |
|
223 |
+ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); |
|
224 | 224 |
return 0; |
225 | 225 |
} |
226 | 226 |
if (padding != RSA_PKCS1_PADDING) |
227 | 227 |
{ |
228 | 228 |
/* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */ |
229 |
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); |
|
229 |
+ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); |
|
230 | 230 |
return 0; |
231 | 231 |
} |
232 | 232 |
/* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would |
... | ... |
@@ -236,7 +237,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i |
236 | 236 |
/* For now, we only support NID_md5_sha1 */ |
237 | 237 |
if (flen != SSL_SIG_LENGTH) |
238 | 238 |
{ |
239 |
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); |
|
239 |
+ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); |
|
240 | 240 |
return 0; |
241 | 241 |
} |
242 | 242 |
if (!CryptCreateHash(cd->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) |
... | ... |
@@ -253,7 +254,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i |
253 | 253 |
} |
254 | 254 |
if ((int) hash_size != flen) |
255 | 255 |
{ |
256 |
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); |
|
256 |
+ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH); |
|
257 | 257 |
CryptDestroyHash(hash); |
258 | 258 |
return 0; |
259 | 259 |
} |
... | ... |
@@ -268,7 +269,7 @@ rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i |
268 | 268 |
buf = malloc(len); |
269 | 269 |
if (buf == NULL) |
270 | 270 |
{ |
271 |
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); |
|
271 |
+ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); |
|
272 | 272 |
CryptDestroyHash(hash); |
273 | 273 |
return 0; |
274 | 274 |
} |
... | ... |
@@ -312,7 +313,8 @@ init(RSA *rsa) |
312 | 312 |
static int |
313 | 313 |
finish(RSA *rsa) |
314 | 314 |
{ |
315 |
- CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data; |
|
315 |
+ const RSA_METHOD *rsa_meth = RSA_get_method(rsa); |
|
316 |
+ CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(rsa_meth); |
|
316 | 317 |
|
317 | 318 |
if (cd == NULL) |
318 | 319 |
{ |
... | ... |
@@ -326,9 +328,8 @@ finish(RSA *rsa) |
326 | 326 |
{ |
327 | 327 |
CertFreeCertificateContext(cd->cert_context); |
328 | 328 |
} |
329 |
- free(rsa->meth->app_data); |
|
330 |
- free((char *) rsa->meth); |
|
331 |
- rsa->meth = NULL; |
|
329 |
+ free(cd); |
|
330 |
+ RSA_meth_free((RSA_METHOD*) rsa_meth); |
|
332 | 331 |
return 1; |
333 | 332 |
} |
334 | 333 |
|
... | ... |
@@ -412,9 +413,9 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) |
412 | 412 |
X509 *cert = NULL; |
413 | 413 |
RSA *rsa = NULL, *pub_rsa; |
414 | 414 |
CAPI_DATA *cd = calloc(1, sizeof(*cd)); |
415 |
- RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method)); |
|
415 |
+ RSA_METHOD *my_rsa_method = NULL; |
|
416 | 416 |
|
417 |
- if (cd == NULL || my_rsa_method == NULL) |
|
417 |
+ if (cd == NULL) |
|
418 | 418 |
{ |
419 | 419 |
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE); |
420 | 420 |
goto err; |
... | ... |
@@ -469,15 +470,16 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) |
469 | 469 |
/* here we don't need to do CryptGetUserKey() or anything; all necessary key |
470 | 470 |
* info is in cd->cert_context, and then, in cd->crypt_prov. */ |
471 | 471 |
|
472 |
- my_rsa_method->name = "Microsoft CryptoAPI RSA Method"; |
|
473 |
- my_rsa_method->rsa_pub_enc = rsa_pub_enc; |
|
474 |
- my_rsa_method->rsa_pub_dec = rsa_pub_dec; |
|
475 |
- my_rsa_method->rsa_priv_enc = rsa_priv_enc; |
|
476 |
- my_rsa_method->rsa_priv_dec = rsa_priv_dec; |
|
477 |
- /* my_rsa_method->init = init; */ |
|
478 |
- my_rsa_method->finish = finish; |
|
479 |
- my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK; |
|
480 |
- my_rsa_method->app_data = (char *) cd; |
|
472 |
+ my_rsa_method = RSA_meth_new("Microsoft Cryptography API RSA Method", |
|
473 |
+ RSA_METHOD_FLAG_NO_CHECK); |
|
474 |
+ check_malloc_return(my_rsa_method); |
|
475 |
+ RSA_meth_set_pub_enc(my_rsa_method, rsa_pub_enc); |
|
476 |
+ RSA_meth_set_pub_dec(my_rsa_method, rsa_pub_dec); |
|
477 |
+ RSA_meth_set_priv_enc(my_rsa_method, rsa_priv_enc); |
|
478 |
+ RSA_meth_set_priv_dec(my_rsa_method, rsa_priv_dec); |
|
479 |
+ RSA_meth_set_init(my_rsa_method, NULL); |
|
480 |
+ RSA_meth_set_finish(my_rsa_method, finish); |
|
481 |
+ RSA_meth_set0_app_data(my_rsa_method, cd); |
|
481 | 482 |
|
482 | 483 |
rsa = RSA_new(); |
483 | 484 |
if (rsa == NULL) |
... | ... |
@@ -486,23 +488,35 @@ SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop) |
486 | 486 |
goto err; |
487 | 487 |
} |
488 | 488 |
|
489 |
- /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(), |
|
489 |
+ /* Public key in cert is NULL until we call SSL_CTX_use_certificate(), |
|
490 | 490 |
* so we do it here then... */ |
491 | 491 |
if (!SSL_CTX_use_certificate(ssl_ctx, cert)) |
492 | 492 |
{ |
493 | 493 |
goto err; |
494 | 494 |
} |
495 | 495 |
/* the public key */ |
496 |
- pub_rsa = cert->cert_info->key->pkey->pkey.rsa; |
|
496 |
+ EVP_PKEY *pkey = X509_get0_pubkey(cert); |
|
497 |
+ |
|
497 | 498 |
/* SSL_CTX_use_certificate() increased the reference count in 'cert', so |
498 | 499 |
* we decrease it here with X509_free(), or it will never be cleaned up. */ |
499 | 500 |
X509_free(cert); |
500 | 501 |
cert = NULL; |
501 | 502 |
|
502 |
- /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */ |
|
503 |
- /* rsa->n indicates the key size */ |
|
504 |
- rsa->n = BN_dup(pub_rsa->n); |
|
505 |
- rsa->flags |= RSA_FLAG_EXT_PKEY; |
|
503 |
+ if (!(pub_rsa = EVP_PKEY_get0_RSA(pkey))) |
|
504 |
+ { |
|
505 |
+ msg(M_WARN, "cryptoapicert requires an RSA certificate"); |
|
506 |
+ goto err; |
|
507 |
+ } |
|
508 |
+ |
|
509 |
+ /* Our private key is external, so we fill in only n and e from the public key */ |
|
510 |
+ const BIGNUM *n = NULL; |
|
511 |
+ const BIGNUM *e = NULL; |
|
512 |
+ RSA_get0_key(pub_rsa, &n, &e, NULL); |
|
513 |
+ if (!RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL)) |
|
514 |
+ { |
|
515 |
+ goto err; |
|
516 |
+ } |
|
517 |
+ RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY); |
|
506 | 518 |
if (!RSA_set_method(rsa, my_rsa_method)) |
507 | 519 |
{ |
508 | 520 |
goto err; |
... | ... |
@@ -624,6 +624,20 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) |
624 | 624 |
} |
625 | 625 |
#endif |
626 | 626 |
|
627 |
+#if !defined(HAVE_RSA_METH_GET0_APP_DATA) |
|
628 |
+/** |
|
629 |
+ * Get the application data of an RSA_METHOD object |
|
630 |
+ * |
|
631 |
+ * @param meth The RSA_METHOD object |
|
632 |
+ * @return pointer to application data, may be NULL |
|
633 |
+ */ |
|
634 |
+static inline void * |
|
635 |
+RSA_meth_get0_app_data(const RSA_METHOD *meth) |
|
636 |
+{ |
|
637 |
+ return meth ? meth->app_data : NULL; |
|
638 |
+} |
|
639 |
+#endif |
|
640 |
+ |
|
627 | 641 |
#if !defined(HAVE_EC_GROUP_ORDER_BITS) && !defined(OPENSSL_NO_EC) |
628 | 642 |
/** |
629 | 643 |
* Gets the number of bits of the order of an EC_GROUP |