diff --git a/lib/hcrypto/rsa.c b/lib/hcrypto/rsa.c index b84dd80e0..6a883454a 100644 --- a/lib/hcrypto/rsa.c +++ b/lib/hcrypto/rsa.c @@ -559,3 +559,38 @@ i2d_RSAPublicKey(RSA *rsa, unsigned char **pp) return size; } + +RSA * +d2i_RSAPublicKey(RSA *rsa, const unsigned char **pp, size_t len) +{ + RSAPublicKey data; + RSA *k = rsa; + size_t size; + int ret; + + ret = decode_RSAPublicKey(*pp, len, &data, &size); + if (ret) + return NULL; + + *pp += size; + + if (k == NULL) { + k = RSA_new(); + if (k == NULL) { + free_RSAPublicKey(&data); + return NULL; + } + } + + k->n = heim_int2BN(&data.modulus); + k->e = heim_int2BN(&data.publicExponent); + + free_RSAPublicKey(&data); + + if (k->n == NULL || k->e == NULL) { + RSA_free(k); + return NULL; + } + + return k; +} diff --git a/lib/hcrypto/rsa.h b/lib/hcrypto/rsa.h index 257e7f01c..9354aaaa4 100644 --- a/lib/hcrypto/rsa.h +++ b/lib/hcrypto/rsa.h @@ -64,6 +64,7 @@ #define d2i_RSAPrivateKey hc_d2i_RSAPrivateKey #define i2d_RSAPrivateKey hc_i2d_RSAPrivateKey #define i2d_RSAPublicKey hc_i2d_RSAPublicKey +#define d2i_RSAPublicKey hc_d2i_RSAPublicKey /* * @@ -173,5 +174,6 @@ RSA * d2i_RSAPrivateKey(RSA *, const unsigned char **, size_t); int i2d_RSAPrivateKey(RSA *, unsigned char **); int i2d_RSAPublicKey(RSA *, unsigned char **); +RSA * d2i_RSAPublicKey(RSA *, const unsigned char **, size_t); #endif /* _HEIM_RSA_H */ diff --git a/lib/hx509/crypto.c b/lib/hx509/crypto.c index 7c086bc7c..03e3dfb66 100644 --- a/lib/hx509/crypto.c +++ b/lib/hx509/crypto.c @@ -550,32 +550,17 @@ rsa_verify_signature(hx509_context context, int tosize, retsize; int ret; RSA *rsa; - RSAPublicKey pk; size_t size; + const unsigned char *p; memset(&di, 0, sizeof(di)); spi = &signer->tbsCertificate.subjectPublicKeyInfo; - rsa = RSA_new(); + p = spi->subjectPublicKey.data; + + rsa = d2i_RSAPublicKey(NULL, &p, size); if (rsa == NULL) { - hx509_set_error_string(context, 0, ENOMEM, "out of memory"); - return ENOMEM; - } - ret = decode_RSAPublicKey(spi->subjectPublicKey.data, - spi->subjectPublicKey.length / 8, - &pk, &size); - if (ret) { - hx509_set_error_string(context, 0, ret, "Failed to decode RSAPublicKey"); - goto out; - } - - rsa->n = heim_int2BN(&pk.modulus); - rsa->e = heim_int2BN(&pk.publicExponent); - - free_RSAPublicKey(&pk); - - if (rsa->n == NULL || rsa->e == NULL) { ret = ENOMEM; hx509_set_error_string(context, 0, ret, "out of memory"); goto out; @@ -650,6 +635,7 @@ rsa_verify_signature(hx509_context context, } free(to); } + ret = 0; out: free_DigestInfo(&di); @@ -1501,7 +1487,10 @@ _hx509_verify_signature(hx509_context context, const heim_octet_string *sig) { const struct signature_alg *md; - const Certificate *signer = _hx509_get_cert(cert); + const Certificate *signer = NULL; + + if (cert) + signer = _hx509_get_cert(cert); md = find_sig_alg(&alg->algorithm); if (md == NULL) {