From: Tobias Brunner Date: Mon, 28 Feb 2022 13:28:18 +0000 (+0100) Subject: openssl: Fixes for RSA with OpenSSL 3.0 X-Git-Tag: 5.9.6rc1~1^2~9 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=21b586c61c95756add73aaeaaa292571565bdb4c;p=thirdparty%2Fstrongswan.git openssl: Fixes for RSA with OpenSSL 3.0 --- diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index b881c81056..7ea53b858b 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -723,10 +723,8 @@ METHOD(plugin_t, get_features, int, /* signature/encryption schemes */ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL), PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL), -#if OPENSSL_VERSION_NUMBER >= 0x10000000L PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS), PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS), -#endif #ifndef OPENSSL_NO_SHA1 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1), PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1), diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c index 15a4ead3da..f8334cba95 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c @@ -31,6 +31,11 @@ #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#include +#endif + /** * Public exponent to use for key generation. */ @@ -41,6 +46,7 @@ OPENSSL_KEY_FALLBACK(RSA, key, n, e, d) OPENSSL_KEY_FALLBACK(RSA, factors, p, q) OPENSSL_KEY_FALLBACK(RSA, crt_params, dmp1, dmq1, iqmp) #define BN_secure_new() BN_new() +#define BN_CTX_secure_new() BN_CTX_new() #endif typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t; @@ -55,9 +61,9 @@ struct private_openssl_rsa_private_key_t { openssl_rsa_private_key_t public; /** - * RSA object from OpenSSL + * RSA key object */ - RSA *rsa; + EVP_PKEY *key; /** * TRUE if the key is from an OpenSSL ENGINE and might not be readable @@ -71,9 +77,7 @@ struct private_openssl_rsa_private_key_t { }; /* implemented in rsa public key */ -bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp); - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L +bool openssl_rsa_fingerprint(EVP_PKEY *key, cred_encoding_type_t type, chunk_t *fp); /** * Build RSA signature @@ -84,20 +88,14 @@ static bool build_signature(private_openssl_rsa_private_key_t *this, { EVP_PKEY_CTX *pctx = NULL; EVP_MD_CTX *mctx = NULL; - EVP_PKEY *key; bool success = FALSE; mctx = EVP_MD_CTX_create(); - key = EVP_PKEY_new(); - if (!mctx || !key) + if (!mctx) { - goto error; - } - if (!EVP_PKEY_set1_RSA(key, this->rsa)) - { - goto error; + return FALSE; } - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, key) <= 0) + if (EVP_DigestSignInit(mctx, &pctx, md, NULL, this->key) <= 0) { goto error; } @@ -118,15 +116,29 @@ static bool build_signature(private_openssl_rsa_private_key_t *this, success = (EVP_DigestSignFinal(mctx, sig->ptr, &sig->len) == 1); error: - if (key) - { - EVP_PKEY_free(key); - } - if (mctx) + EVP_MD_CTX_destroy(mctx); + return success; +} + +/** + * Build an EMSA PKCS1 signature without hashing + */ +static bool build_plain_signature(private_openssl_rsa_private_key_t *this, + chunk_t data, chunk_t *sig) +{ + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new(this->key, NULL); + if (!ctx || + EVP_PKEY_sign_init(ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0 || + EVP_PKEY_sign(ctx, sig->ptr, &sig->len, data.ptr, data.len) <= 0) { - EVP_MD_CTX_destroy(mctx); + EVP_PKEY_CTX_free(ctx); + return FALSE; } - return success; + EVP_PKEY_CTX_free(ctx); + return TRUE; } /** @@ -137,12 +149,11 @@ static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this, { const EVP_MD *md; - *sig = chunk_alloc(RSA_size(this->rsa)); + *sig = chunk_alloc(EVP_PKEY_size(this->key)); if (type == NID_undef) { - if (RSA_private_encrypt(data.len, data.ptr, sig->ptr, this->rsa, - RSA_PKCS1_PADDING) == sig->len) + if (build_plain_signature(this, data, sig)) { return TRUE; } @@ -173,7 +184,7 @@ static bool build_emsa_pss_signature(private_openssl_rsa_private_key_t *this, return FALSE; } - *sig = chunk_alloc(RSA_size(this->rsa)); + *sig = chunk_alloc(EVP_PKEY_size(this->key)); md = openssl_get_md(params->hash); if (md && build_signature(this, md, params, data, sig)) @@ -184,80 +195,6 @@ static bool build_emsa_pss_signature(private_openssl_rsa_private_key_t *this, return FALSE; } -#else /* OPENSSL_VERSION_NUMBER < 1.0 */ - -/** - * Build an EMSA PKCS1 signature described in PKCS#1 - */ -static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this, - int type, chunk_t data, chunk_t *sig) -{ - bool success = FALSE; - - *sig = chunk_alloc(RSA_size(this->rsa)); - - if (type == NID_undef) - { - if (RSA_private_encrypt(data.len, data.ptr, sig->ptr, this->rsa, - RSA_PKCS1_PADDING) == sig->len) - { - success = TRUE; - } - } - else - { - EVP_MD_CTX *ctx = NULL; - EVP_PKEY *key = NULL; - const EVP_MD *hasher; - u_int len; - - hasher = EVP_get_digestbynid(type); - if (!hasher) - { - goto error; - } - - ctx = EVP_MD_CTX_create(); - key = EVP_PKEY_new(); - if (!ctx || !key) - { - goto error; - } - if (!EVP_PKEY_set1_RSA(key, this->rsa)) - { - goto error; - } - if (!EVP_SignInit_ex(ctx, hasher, NULL)) - { - goto error; - } - if (!EVP_SignUpdate(ctx, data.ptr, data.len)) - { - goto error; - } - if (EVP_SignFinal(ctx, sig->ptr, &len, key)) - { - success = TRUE; - } - -error: - if (key) - { - EVP_PKEY_free(key); - } - if (ctx) - { - EVP_MD_CTX_destroy(ctx); - } - } - if (!success) - { - free(sig->ptr); - } - return success; -} -#endif /* OPENSSL_VERSION_NUMBER < 1.0 */ - METHOD(private_key_t, get_type, key_type_t, private_openssl_rsa_private_key_t *this) { @@ -294,10 +231,8 @@ METHOD(private_key_t, sign, bool, return build_emsa_pkcs1_signature(this, NID_sha1, data, signature); case SIGN_RSA_EMSA_PKCS1_MD5: return build_emsa_pkcs1_signature(this, NID_md5, data, signature); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L case SIGN_RSA_EMSA_PSS: return build_emsa_pss_signature(this, params, data, signature); -#endif default: DBG1(DBG_LIB, "signature scheme %N not supported in RSA", signature_scheme_names, scheme); @@ -310,7 +245,6 @@ METHOD(private_key_t, decrypt, bool, void *params, chunk_t crypto, chunk_t *plain) { EVP_PKEY_CTX *ctx = NULL; - EVP_PKEY *evp_key = NULL; chunk_t label = chunk_empty; hash_algorithm_t hash_alg = HASH_UNKNOWN; size_t len; @@ -349,23 +283,11 @@ METHOD(private_key_t, decrypt, bool, return FALSE; } - evp_key = EVP_PKEY_new(); - if (!evp_key) - { - DBG1(DBG_LIB, "could not create EVP key"); - goto error; - } - if (EVP_PKEY_set1_RSA(evp_key, this->rsa) <= 0) - { - DBG1(DBG_LIB, "could not set EVP key to RSA key"); - goto error; - } - - ctx = EVP_PKEY_CTX_new(evp_key, NULL); + ctx = EVP_PKEY_CTX_new(this->key, NULL); if (!ctx) { DBG1(DBG_LIB, "could not create EVP context"); - goto error; + return FALSE; } if (EVP_PKEY_decrypt_init(ctx) <= 0) @@ -410,7 +332,7 @@ METHOD(private_key_t, decrypt, bool, } /* determine maximum plaintext size */ - len = RSA_size(this->rsa); + len = EVP_PKEY_size(this->key); decrypted = malloc(len); /* decrypt data */ @@ -424,33 +346,23 @@ METHOD(private_key_t, decrypt, bool, success = TRUE; error: - if (ctx) - { - EVP_PKEY_CTX_free(ctx); - } - if (evp_key) - { - EVP_PKEY_free(evp_key); - } + EVP_PKEY_CTX_free(ctx); return success; } METHOD(private_key_t, get_keysize, int, private_openssl_rsa_private_key_t *this) { - return RSA_size(this->rsa) * 8; + return EVP_PKEY_bits(this->key); } METHOD(private_key_t, get_public_key, public_key_t*, private_openssl_rsa_private_key_t *this) { - chunk_t enc; public_key_t *key; - u_char *p; + chunk_t enc; - enc = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL)); - p = enc.ptr; - i2d_RSAPublicKey(this->rsa, &p); + enc = openssl_i2chunk(PublicKey, this->key); key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_ASN1_DER, enc, BUILD_END); free(enc.ptr); @@ -461,15 +373,13 @@ METHOD(private_key_t, get_fingerprint, bool, private_openssl_rsa_private_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint) { - return openssl_rsa_fingerprint(this->rsa, type, fingerprint); + return openssl_rsa_fingerprint(this->key, type, fingerprint); } METHOD(private_key_t, get_encoding, bool, private_openssl_rsa_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding) { - u_char *p; - if (this->engine) { return FALSE; @@ -481,9 +391,7 @@ METHOD(private_key_t, get_encoding, bool, { bool success = TRUE; - *encoding = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL)); - p = encoding->ptr; - i2d_RSAPrivateKey(this->rsa, &p); + *encoding = openssl_i2chunk(PrivateKey, this->key); if (type == PRIVKEY_PEM) { @@ -513,10 +421,10 @@ METHOD(private_key_t, destroy, void, { if (ref_put(&this->ref)) { - if (this->rsa) + if (this->key) { - lib->encoding->clear_cache(lib->encoding, this->rsa); - RSA_free(this->rsa); + lib->encoding->clear_cache(lib->encoding, this->key); + EVP_PKEY_free(this->key); } free(this); } @@ -525,7 +433,7 @@ METHOD(private_key_t, destroy, void, /** * Internal generic constructor */ -static private_openssl_rsa_private_key_t *create_empty() +static private_openssl_rsa_private_key_t *create_internal(EVP_PKEY *key) { private_openssl_rsa_private_key_t *this; @@ -547,6 +455,7 @@ static private_openssl_rsa_private_key_t *create_empty() }, }, .ref = 1, + .key = key, ); return this; @@ -559,9 +468,9 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type, va_list args) { private_openssl_rsa_private_key_t *this; + EVP_PKEY *key = NULL; u_int key_size = 0; - RSA *rsa = NULL; - BIGNUM *e = NULL; + BIGNUM *e; while (TRUE) { @@ -584,28 +493,53 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type, e = BN_new(); if (!e || !BN_set_word(e, PUBLIC_EXPONENT)) { - goto error; + BN_free(e); + return NULL; } - rsa = RSA_new(); - if (!rsa || !RSA_generate_key_ex(rsa, key_size, e, NULL)) + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + /* EVP_RSA_gen() does not allow specifying the public exponent, the default + * value is the same, but let's still use this more flexible approach */ + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (!ctx || + EVP_PKEY_keygen_init(ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_size) <= 0 || + EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) <= 0 || + EVP_PKEY_keygen(ctx, &key) <= 0) { - goto error; + EVP_PKEY_CTX_free(ctx); + return NULL; } - this = create_empty(); - this->rsa = rsa; - BN_free(e); - return &this->public; + EVP_PKEY_CTX_free(ctx); +#else /* OPENSSL_VERSION_NUMBER */ + RSA *rsa = RSA_new(); -error: - if (e) + if (RSA_generate_key_ex(rsa, key_size, e, NULL)) { - BN_free(e); + key = EVP_PKEY_new(); + if (!EVP_PKEY_assign_RSA(key, rsa)) + { + RSA_free(rsa); + EVP_PKEY_free(key); + key = NULL; + } } - if (rsa) + else { RSA_free(rsa); } - return NULL; +#endif /* OPENSSL_VERSION_NUMBER */ + + if (!key) + { + BN_free(e); + return NULL; + } + this = create_internal(key); + BN_free(e); + return &this->public; } /* @@ -614,16 +548,13 @@ error: private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key, bool engine) { private_openssl_rsa_private_key_t *this; - RSA *rsa; - rsa = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); - if (!rsa) + if (EVP_PKEY_base_id(key) != EVP_PKEY_RSA) { + EVP_PKEY_free(key); return NULL; } - this = create_empty(); - this->rsa = rsa; + this = create_internal(key); this->engine = engine; return &this->public.key; } @@ -632,19 +563,13 @@ private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key, bool engine) * Recover the primes from n, e and d using the algorithm described in * Appendix C of NIST SP 800-56B. */ -static bool calculate_pq(BIGNUM *n, BIGNUM *e, BIGNUM *d, - BIGNUM **p, BIGNUM **q) +static bool calculate_pq(BN_CTX *ctx, BIGNUM *n, BIGNUM *e, BIGNUM *d, + BIGNUM *p, BIGNUM *q) { - BN_CTX *ctx; BIGNUM *k, *r, *g, *y, *n1, *x; int i, t, j; bool success = FALSE; - ctx = BN_CTX_new(); - if (!ctx) - { - return FALSE; - } BN_CTX_start(ctx); k = BN_CTX_get(ctx); r = BN_CTX_get(ctx); @@ -685,7 +610,7 @@ static bool calculate_pq(BIGNUM *n, BIGNUM *e, BIGNUM *d, } for (i = 0; i < 100; i++) { /* generate random integer g in [0, n-1] */ - if (!BN_pseudo_rand_range(g, n)) + if (!BN_rand_range(g, n)) { goto error; } @@ -730,25 +655,19 @@ done: { goto error; } - *p = BN_secure_new(); - if (!BN_gcd(*p, y, n, ctx)) + if (!BN_gcd(p, y, n, ctx)) { - BN_clear_free(*p); goto error; } /* q = n/p */ - *q = BN_secure_new(); - if (!BN_div(*q, NULL, n, *p, ctx)) + if (!BN_div(q, NULL, n, p, ctx)) { - BN_clear_free(*p); - BN_clear_free(*q); goto error; } success = TRUE; error: BN_CTX_end(ctx); - BN_CTX_free(ctx); return success; } @@ -756,65 +675,31 @@ error: * Calculates dp = d (mod p-1) or dq = d (mod q-1) for the Chinese remainder * algorithm. */ -static BIGNUM *dmodpq1(BIGNUM *d, BIGNUM *pq) +static bool dmodpq1(BN_CTX *ctx, BIGNUM *d, BIGNUM *pq, BIGNUM *res) { - BN_CTX *ctx; - BIGNUM *res = NULL, *pq1; + BIGNUM *pq1; - ctx = BN_CTX_new(); - if (!ctx) - { - return NULL; - } BN_CTX_start(ctx); pq1 = BN_CTX_get(ctx); - /* p|q - 1 */ - if (!BN_sub(pq1, pq, BN_value_one())) + /* p|q - 1 + * d (mod p|q -1) */ + if (!BN_sub(pq1, pq, BN_value_one()) || + !BN_mod(res, d, pq1, ctx)) { - goto error; - } - /* d (mod p|q -1) */ - res = BN_secure_new(); - if (!BN_mod(res, d, pq1, ctx)) - { - BN_clear_free(res); - res = NULL; - goto error; + BN_CTX_end(ctx); + return FALSE; } - -error: BN_CTX_end(ctx); - BN_CTX_free(ctx); - return res; + return TRUE; } /** * Calculates qinv = q^-1 (mod p) for the Chinese remainder algorithm. */ -static BIGNUM *qinv(BIGNUM *q, BIGNUM *p) +static bool qinv(BN_CTX *ctx, BIGNUM *q, BIGNUM *p, BIGNUM *res) { - BN_CTX *ctx; - BIGNUM *res = NULL; - - ctx = BN_CTX_new(); - if (!ctx) - { - return NULL; - } - BN_CTX_start(ctx); /* q^-1 (mod p) */ - res = BN_secure_new(); - if (!BN_mod_inverse(res, q, p, ctx)) - { - BN_clear_free(res); - res = NULL; - goto error; - } - -error: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return res; + return BN_mod_inverse(res, q, p, ctx); } /* @@ -824,6 +709,7 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type, va_list args) { private_openssl_rsa_private_key_t *this; + EVP_PKEY *key = NULL; chunk_t blob, n, e, d, p, q, exp1, exp2, coeff; blob = n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty; @@ -866,79 +752,126 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type, break; } - this = create_empty(); if (blob.ptr) { - this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len); - if (this->rsa && RSA_check_key(this->rsa) == 1) - { - return &this->public; - } + key = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (const u_char**)&blob.ptr, + blob.len); } else if (n.ptr && e.ptr && d.ptr) { - BIGNUM *bn_n, *bn_e, *bn_d, *bn_p, *bn_q; - BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; + BN_CTX *ctx; + BIGNUM *bn_n, *bn_e, *bn_d, *bn_p, *bn_q, *dmp1, *dmq1, *iqmp; - this->rsa = RSA_new(); - - bn_n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); - bn_e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); - bn_d = BN_bin2bn((const u_char*)d.ptr, d.len, NULL); - if (!RSA_set0_key(this->rsa, bn_n, bn_e, bn_d)) + ctx = BN_CTX_secure_new(); + if (!ctx) { goto error; - } + BN_CTX_start(ctx); + bn_n = BN_CTX_get(ctx); + bn_e = BN_CTX_get(ctx); + bn_d = BN_CTX_get(ctx); + bn_p = BN_CTX_get(ctx); + bn_q = BN_CTX_get(ctx); + dmp1 = BN_CTX_get(ctx); + dmq1 = BN_CTX_get(ctx); + iqmp = BN_CTX_get(ctx); + + bn_n = BN_bin2bn((const u_char*)n.ptr, n.len, bn_n); + bn_e = BN_bin2bn((const u_char*)e.ptr, e.len, bn_e); + bn_d = BN_bin2bn((const u_char*)d.ptr, d.len, bn_d); if (p.ptr && q.ptr) { - bn_p = BN_bin2bn((const u_char*)p.ptr, p.len, NULL); - bn_q = BN_bin2bn((const u_char*)q.ptr, q.len, NULL); + bn_p = BN_bin2bn((const u_char*)p.ptr, p.len, bn_p); + bn_q = BN_bin2bn((const u_char*)q.ptr, q.len, bn_q); } - else - { - if (!calculate_pq(bn_n, bn_e, bn_d, &bn_p, &bn_q)) - { - goto error; - } - } - if (!RSA_set0_factors(this->rsa, bn_p, bn_q)) + else if (!calculate_pq(ctx, bn_n, bn_e, bn_d, bn_p, bn_q)) { goto error; } if (exp1.ptr) { - dmp1 = BN_bin2bn((const u_char*)exp1.ptr, exp1.len, NULL); + dmp1 = BN_bin2bn((const u_char*)exp1.ptr, exp1.len, dmp1); } - else + else if (!dmodpq1(ctx, bn_d, bn_p, dmp1)) { - dmp1 = dmodpq1(bn_d, bn_p); + goto error; } if (exp2.ptr) { - dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, NULL); + dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, dmq1); } - else + else if (!dmodpq1(ctx, bn_d, bn_q, dmq1)) { - dmq1 = dmodpq1(bn_d, bn_q); + goto error; } if (coeff.ptr) { - iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, NULL); + iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, iqmp); } - else + else if (!qinv(ctx, bn_q, bn_p, iqmp)) { - iqmp = qinv(bn_q, bn_p); + goto error; } - if (RSA_set0_crt_params(this->rsa, dmp1, dmq1, iqmp) && - RSA_check_key(this->rsa) == 1) + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PARAM_BLD *bld; + OSSL_PARAM *params = NULL; + EVP_PKEY_CTX *pctx; + + bld = OSSL_PARAM_BLD_new(); + if (bld && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, bn_n) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, bn_e) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, bn_d) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR1, bn_p) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR2, bn_q) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp)) { - return &this->public; + params = OSSL_PARAM_BLD_to_param(bld); } - } + OSSL_PARAM_BLD_free(bld); + + pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!params || !pctx || + EVP_PKEY_fromdata_init(pctx) <= 0 || + EVP_PKEY_fromdata(pctx, &key, EVP_PKEY_KEYPAIR, params) <= 0) + { + key = NULL; + } + EVP_PKEY_CTX_free(pctx); + OSSL_PARAM_free(params); +#else /* OPENSSL_VERSION_NUMBER */ + RSA *rsa = RSA_new(); + if (!RSA_set0_key(rsa, BN_dup(bn_n), BN_dup(bn_e), BN_dup(bn_d)) || + !RSA_set0_factors(rsa, BN_dup(bn_p), BN_dup(bn_q)) || + !RSA_set0_crt_params(rsa, BN_dup(dmp1), BN_dup(dmq1), BN_dup(iqmp)) || + RSA_check_key(rsa) <= 0) + { + RSA_free(rsa); + goto error; + } + key = EVP_PKEY_new(); + if (!EVP_PKEY_assign_RSA(key, rsa)) + { + RSA_free(rsa); + EVP_PKEY_free(key); + key = NULL; + } +#endif /* OPENSSL_VERSION_NUMBER */ + error: - destroy(this); - return NULL; + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (!key) + { + return NULL; + } + this = create_internal(key); + return &this->public; } #endif /* OPENSSL_NO_RSA */ diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index d5c9eed1ea..43ebe03623 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -31,6 +31,11 @@ #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#include +#endif + #if OPENSSL_VERSION_NUMBER < 0x10100000L OPENSSL_KEY_FALLBACK(RSA, key, n, e, d) #endif @@ -47,9 +52,9 @@ struct private_openssl_rsa_public_key_t { openssl_rsa_public_key_t public; /** - * RSA object from OpenSSL + * RSA key object */ - RSA *rsa; + EVP_PKEY *key; /** * reference counter @@ -57,9 +62,6 @@ struct private_openssl_rsa_public_key_t { refcount_t ref; }; - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - /** * Verify RSA signature */ @@ -69,8 +71,7 @@ static bool verify_signature(private_openssl_rsa_public_key_t *this, { EVP_PKEY_CTX *pctx = NULL; EVP_MD_CTX *mctx = NULL; - EVP_PKEY *key; - int rsa_size = RSA_size(this->rsa); + int rsa_size = EVP_PKEY_size(this->key); bool valid = FALSE; /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */ @@ -80,16 +81,11 @@ static bool verify_signature(private_openssl_rsa_public_key_t *this, } mctx = EVP_MD_CTX_create(); - key = EVP_PKEY_new(); - if (!mctx || !key) - { - goto error; - } - if (!EVP_PKEY_set1_RSA(key, this->rsa)) + if (!mctx) { - goto error; + return FALSE; } - if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, key) <= 0) + if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, this->key) <= 0) { goto error; } @@ -110,14 +106,7 @@ static bool verify_signature(private_openssl_rsa_public_key_t *this, valid = (EVP_DigestVerifyFinal(mctx, signature.ptr, signature.len) == 1); error: - if (key) - { - EVP_PKEY_free(key); - } - if (mctx) - { - EVP_MD_CTX_destroy(mctx); - } + EVP_MD_CTX_destroy(mctx); return valid; } @@ -128,7 +117,7 @@ static bool verify_plain_signature(private_openssl_rsa_public_key_t *this, chunk_t data, chunk_t signature) { char *buf; - int len, rsa_size = RSA_size(this->rsa); + size_t rsa_size = EVP_PKEY_size(this->key); bool valid = FALSE; /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */ @@ -136,14 +125,39 @@ static bool verify_plain_signature(private_openssl_rsa_public_key_t *this, { signature = chunk_skip(signature, signature.len - rsa_size); } +#if defined(OPENSSL_IS_BORINGSSL) && \ + (!defined(BORINGSSL_API_VERSION) || BORINGSSL_API_VERSION < 10) + RSA *rsa = EVP_PKEY_get1_RSA(this->key); + int len; + buf = malloc(rsa_size); - len = RSA_public_decrypt(signature.len, signature.ptr, buf, this->rsa, + len = RSA_public_decrypt(signature.len, signature.ptr, buf, rsa, RSA_PKCS1_PADDING); if (len != -1) { valid = chunk_equals_const(data, chunk_create(buf, len)); } + RSA_free(rsa); +#else + EVP_PKEY_CTX *ctx; + size_t len = rsa_size; + + ctx = EVP_PKEY_CTX_new(this->key, NULL); + if (!ctx || + EVP_PKEY_verify_recover_init(ctx) <= 0 || + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) + { + EVP_PKEY_CTX_free(ctx); + return FALSE; + } + buf = malloc(rsa_size); + if (EVP_PKEY_verify_recover(ctx, buf, &len, signature.ptr, signature.len) > 0) + { + valid = chunk_equals_const(data, chunk_create(buf, len)); + } free(buf); + EVP_PKEY_CTX_free(ctx); +#endif return valid; } @@ -180,85 +194,6 @@ static bool verify_emsa_pss_signature(private_openssl_rsa_public_key_t *this, return md && verify_signature(this, md, params, data, signature); } -#else /* OPENSSL_VERSION_NUMBER < 1.0 */ - -/** - * Verification of an EMSA PKCS1 signature described in PKCS#1 - */ -static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this, - int type, chunk_t data, chunk_t signature) -{ - bool valid = FALSE; - int rsa_size = RSA_size(this->rsa); - - /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */ - if (signature.len > rsa_size) - { - signature = chunk_skip(signature, signature.len - rsa_size); - } - - if (type == NID_undef) - { - char *buf; - int len; - - buf = malloc(rsa_size); - len = RSA_public_decrypt(signature.len, signature.ptr, buf, this->rsa, - RSA_PKCS1_PADDING); - if (len != -1) - { - valid = chunk_equals_const(data, chunk_create(buf, len)); - } - free(buf); - } - else - { - EVP_MD_CTX *ctx; - EVP_PKEY *key; - const EVP_MD *hasher; - - hasher = EVP_get_digestbynid(type); - if (!hasher) - { - return FALSE; - } - - ctx = EVP_MD_CTX_create(); - key = EVP_PKEY_new(); - - if (!ctx || !key) - { - goto error; - } - if (!EVP_PKEY_set1_RSA(key, this->rsa)) - { - goto error; - } - if (!EVP_VerifyInit_ex(ctx, hasher, NULL)) - { - goto error; - } - if (!EVP_VerifyUpdate(ctx, data.ptr, data.len)) - { - goto error; - } - valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1); - -error: - if (key) - { - EVP_PKEY_free(key); - } - if (ctx) - { - EVP_MD_CTX_destroy(ctx); - } - } - return valid; -} - -#endif /* OPENSSL_VERSION_NUMBER < 1.0 */ - METHOD(public_key_t, get_type, key_type_t, private_openssl_rsa_public_key_t *this) { @@ -295,10 +230,8 @@ METHOD(public_key_t, verify, bool, return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature); case SIGN_RSA_EMSA_PKCS1_MD5: return verify_emsa_pkcs1_signature(this, NID_md5, data, signature); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L case SIGN_RSA_EMSA_PSS: return verify_emsa_pss_signature(this, params, data, signature); -#endif default: DBG1(DBG_LIB, "signature scheme %N not supported in RSA", signature_scheme_names, scheme); @@ -311,7 +244,6 @@ METHOD(public_key_t, encrypt, bool, void *params, chunk_t plain, chunk_t *crypto) { EVP_PKEY_CTX *ctx = NULL; - EVP_PKEY *evp_key = NULL; chunk_t label = chunk_empty; hash_algorithm_t hash_alg = HASH_UNKNOWN; size_t len; @@ -350,23 +282,11 @@ METHOD(public_key_t, encrypt, bool, return FALSE; } - evp_key = EVP_PKEY_new(); - if (!evp_key) - { - DBG1(DBG_LIB, "could not create EVP key"); - goto error; - } - if (EVP_PKEY_set1_RSA(evp_key, this->rsa) <= 0) - { - DBG1(DBG_LIB, "could not set EVP key to RSA key"); - goto error; - } - - ctx = EVP_PKEY_CTX_new(evp_key, NULL); + ctx = EVP_PKEY_CTX_new(this->key, NULL); if (!ctx) { DBG1(DBG_LIB, "could not create EVP context"); - goto error; + return FALSE; } if (EVP_PKEY_encrypt_init(ctx) <= 0) @@ -411,7 +331,7 @@ METHOD(public_key_t, encrypt, bool, } /* determine maximum ciphertext size */ - len = RSA_size(this->rsa); + len = EVP_PKEY_size(this->key); encrypted = malloc(len); /* decrypt data */ @@ -425,59 +345,91 @@ METHOD(public_key_t, encrypt, bool, success = TRUE; error: - if (ctx) - { - EVP_PKEY_CTX_free(ctx); - } - if (evp_key) - { - EVP_PKEY_free(evp_key); - } + EVP_PKEY_CTX_free(ctx); return success; } METHOD(public_key_t, get_keysize, int, private_openssl_rsa_public_key_t *this) { - return RSA_size(this->rsa) * 8; + return EVP_PKEY_bits(this->key); +} + +/** + * Get n and e of the given RSA key (allocated). + */ +static bool get_n_and_e(EVP_PKEY *key, chunk_t *n, chunk_t *e) +{ + const BIGNUM *cbn_n, *cbn_e; + BIGNUM *bn_n = NULL, *bn_e = NULL; + bool success = FALSE; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_RSA_N, &bn_n) <= 0 || + EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_RSA_E, &bn_e) <= 0) + { + goto error; + } + cbn_n = bn_n; + cbn_e = bn_e; +#elif OPENSSL_VERSION_NUMBER >= 0x1010000fL + RSA *rsa = EVP_PKEY_get0_RSA(key); + RSA_get0_key(rsa, &cbn_n, &cbn_e, NULL); +#else + RSA *rsa = EVP_PKEY_get1_RSA(key); + RSA_get0_key(rsa, &cbn_n, &cbn_e, NULL); + RSA_free(rsa); +#endif + + *n = *e = chunk_empty; + if (!openssl_bn2chunk(cbn_n, n) || + !openssl_bn2chunk(cbn_e, e)) + { + chunk_free(n); + chunk_free(e); + goto error; + } + success = TRUE; + +error: + BN_free(bn_n); + BN_free(bn_e); + return success; } /** * Calculate fingerprint from a RSA key, also used in rsa private key. */ -bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp) +bool openssl_rsa_fingerprint(EVP_PKEY *key, cred_encoding_type_t type, chunk_t *fp) { hasher_t *hasher; - chunk_t key; + chunk_t enc; u_char *p; - if (lib->encoding->get_cache(lib->encoding, type, rsa, fp)) + if (lib->encoding->get_cache(lib->encoding, type, key, fp)) { return TRUE; } switch (type) { case KEYID_PUBKEY_SHA1: - key = chunk_alloc(i2d_RSAPublicKey(rsa, NULL)); - p = key.ptr; - i2d_RSAPublicKey(rsa, &p); + enc = chunk_alloc(i2d_PublicKey(key, NULL)); + p = enc.ptr; + i2d_PublicKey(key, &p); break; case KEYID_PUBKEY_INFO_SHA1: - key = chunk_alloc(i2d_RSA_PUBKEY(rsa, NULL)); - p = key.ptr; - i2d_RSA_PUBKEY(rsa, &p); + enc = chunk_alloc(i2d_PUBKEY(key, NULL)); + p = enc.ptr; + i2d_PUBKEY(key, &p); break; default: { - const BIGNUM *bn_n, *bn_e; chunk_t n = chunk_empty, e = chunk_empty; bool success = FALSE; - RSA_get0_key(rsa, &bn_n, &bn_e, NULL); - if (openssl_bn2chunk(bn_n, &n) && - openssl_bn2chunk(bn_e, &e)) + if (get_n_and_e(key, &n, &e)) { - success = lib->encoding->encode(lib->encoding, type, rsa, fp, + success = lib->encoding->encode(lib->encoding, type, key, fp, CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END); } @@ -487,16 +439,16 @@ bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp) } } hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher || !hasher->allocate_hash(hasher, key, fp)) + if (!hasher || !hasher->allocate_hash(hasher, enc, fp)) { DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed"); DESTROY_IF(hasher); - free(key.ptr); + free(enc.ptr); return FALSE; } - free(key.ptr); + free(enc.ptr); hasher->destroy(hasher); - lib->encoding->cache(lib->encoding, type, rsa, *fp); + lib->encoding->cache(lib->encoding, type, key, *fp); return TRUE; } @@ -504,7 +456,7 @@ METHOD(public_key_t, get_fingerprint, bool, private_openssl_rsa_public_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint) { - return openssl_rsa_fingerprint(this->rsa, type, fingerprint); + return openssl_rsa_fingerprint(this->key, type, fingerprint); } METHOD(public_key_t, get_encoding, bool, @@ -512,16 +464,13 @@ METHOD(public_key_t, get_encoding, bool, chunk_t *encoding) { bool success = FALSE; - u_char *p; switch (type) { case PUBKEY_SPKI_ASN1_DER: case PUBKEY_PEM: { - *encoding = chunk_alloc(i2d_RSA_PUBKEY(this->rsa, NULL)); - p = encoding->ptr; - i2d_RSA_PUBKEY(this->rsa, &p); + *encoding = openssl_i2chunk(PUBKEY, this->key); success = TRUE; if (type == PUBKEY_PEM) @@ -537,19 +486,14 @@ METHOD(public_key_t, get_encoding, bool, } case PUBKEY_ASN1_DER: { - *encoding = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL)); - p = encoding->ptr; - i2d_RSAPublicKey(this->rsa, &p); + *encoding = openssl_i2chunk(PublicKey, this->key); return TRUE; } default: { - const BIGNUM *bn_n, *bn_e; chunk_t n = chunk_empty, e = chunk_empty; - RSA_get0_key(this->rsa, &bn_n, &bn_e, NULL); - if (openssl_bn2chunk(bn_n, &n) && - openssl_bn2chunk(bn_e, &e)) + if (get_n_and_e(this->key, &n, &e)) { success = lib->encoding->encode(lib->encoding, type, NULL, encoding, CRED_PART_RSA_MODULUS, n, @@ -574,10 +518,10 @@ METHOD(public_key_t, destroy, void, { if (ref_put(&this->ref)) { - if (this->rsa) + if (this->key) { - lib->encoding->clear_cache(lib->encoding, this->rsa); - RSA_free(this->rsa); + lib->encoding->clear_cache(lib->encoding, this->key); + EVP_PKEY_free(this->key); } free(this); } @@ -586,7 +530,7 @@ METHOD(public_key_t, destroy, void, /** * Generic private constructor */ -static private_openssl_rsa_public_key_t *create_empty() +static private_openssl_rsa_public_key_t *create_internal(EVP_PKEY *key) { private_openssl_rsa_public_key_t *this; @@ -606,6 +550,7 @@ static private_openssl_rsa_public_key_t *create_empty() }, }, .ref = 1, + .key = key, ); return this; @@ -618,6 +563,7 @@ openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type, va_list args) { private_openssl_rsa_public_key_t *this; + EVP_PKEY *key = NULL; chunk_t blob, n, e; n = e = blob = chunk_empty; @@ -642,41 +588,98 @@ openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type, break; } - this = create_empty(); if (blob.ptr) { switch (type) { case KEY_ANY: - this->rsa = d2i_RSA_PUBKEY(NULL, (const u_char**)&blob.ptr, - blob.len); + key = d2i_PUBKEY(NULL, (const u_char**)&blob.ptr, blob.len); + if (key && EVP_PKEY_base_id(key) != EVP_PKEY_RSA) + { + EVP_PKEY_free(key); + key = NULL; + } break; case KEY_RSA: - this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&blob.ptr, - blob.len); +#if defined(OPENSSL_IS_BORINGSSL) && \ + (!defined(BORINGSSL_API_VERSION) || BORINGSSL_API_VERSION < 10) + { + RSA *rsa = d2i_RSAPublicKey(NULL, (const u_char**)&blob.ptr, + blob.len); + key = EVP_PKEY_new(); + if (!key || !EVP_PKEY_assign_RSA(key, rsa)) + { + RSA_free(rsa); + EVP_PKEY_free(key); + key = NULL; + } + } +#else + key = d2i_PublicKey(EVP_PKEY_RSA, NULL, (const u_char**)&blob.ptr, + blob.len); +#endif break; default: break; } - if (this->rsa) - { - return &this->public; - } } else if (n.ptr && e.ptr && type == KEY_RSA) { BIGNUM *bn_n, *bn_e; - this->rsa = RSA_new(); bn_n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL); bn_e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL); - if (RSA_set0_key(this->rsa, bn_n, bn_e, NULL)) + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PARAM_BLD *bld; + OSSL_PARAM *params = NULL; + EVP_PKEY_CTX *ctx; + + bld = OSSL_PARAM_BLD_new(); + if (bld && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, bn_n) && + OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, bn_e)) + { + params = OSSL_PARAM_BLD_to_param(bld); + } + OSSL_PARAM_BLD_free(bld); + BN_free(bn_n); + BN_free(bn_e); + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (!params || !ctx || + EVP_PKEY_fromdata_init(ctx) <= 0 || + EVP_PKEY_fromdata(ctx, &key, EVP_PKEY_PUBLIC_KEY, params) <= 0) + { + key = NULL; + } + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); +#else /* OPENSSL_VERSION_NUMBER */ + RSA *rsa = RSA_new(); + + if (RSA_set0_key(rsa, bn_n, bn_e, NULL)) + { + key = EVP_PKEY_new(); + if (!key || !EVP_PKEY_assign_RSA(key, rsa)) + { + RSA_free(rsa); + EVP_PKEY_free(key); + key = NULL; + } + } + else { - return &this->public; + RSA_free(rsa); } +#endif /* OPENSSL_VERSION_NUMBER */ + } + if (!key) + { + return NULL; } - destroy(this); - return NULL; + this = create_internal(key); + return &this->public; } #endif /* OPENSSL_NO_RSA */ diff --git a/src/libstrongswan/tests/suites/test_rsa.c b/src/libstrongswan/tests/suites/test_rsa.c index 0ab9dc5c97..33a223d57b 100644 --- a/src/libstrongswan/tests/suites/test_rsa.c +++ b/src/libstrongswan/tests/suites/test_rsa.c @@ -177,6 +177,7 @@ END_TEST static struct { chunk_t key; chunk_t pkcs8; + chunk_t spki; chunk_t pub; chunk_t fp_pk; chunk_t fp_spki; @@ -252,6 +253,14 @@ static struct { 0x4c,0xa9,0xa2,0x42,0xbe,0xdd,0xdb,0xf7,0xd3,0x28,0x07,0x10,0x88,0x53,0x15,0xb2, 0x4f,0xb5,0x9d,0x47,0x9b,0xd6,0xc8,0xfe,0x5b,0xa2,0xd7,0xe1,0x13,0xca,0x0b,0xce, 0x7a,0xed,0xa2,0x3e,0xd5,0x9b,0xb8,0x8b,0x4f,0x02,0x03,0x01,0x00,0x01), + chunk_from_chars( + 0x30,0x68,0x02,0x61,0x00,0xd1,0x5d,0x98,0x97,0x95,0x98,0x19,0x87,0x20,0x3f,0x10, + 0xb0,0x05,0x36,0x1e,0x1b,0xcd,0xc8,0x93,0x66,0xd7,0x43,0xed,0x84,0xb0,0x3e,0x96, + 0xd3,0xe7,0x27,0x0e,0xc0,0xba,0xdf,0x7e,0x32,0x05,0xd3,0x08,0xd6,0x44,0xd5,0x01, + 0x2b,0x3e,0x5d,0xc0,0x37,0xae,0x4f,0xe0,0xea,0x8d,0x2c,0x42,0x4c,0xa9,0xa2,0x42, + 0xbe,0xdd,0xdb,0xf7,0xd3,0x28,0x07,0x10,0x88,0x53,0x15,0xb2,0x4f,0xb5,0x9d,0x47, + 0x9b,0xd6,0xc8,0xfe,0x5b,0xa2,0xd7,0xe1,0x13,0xca,0x0b,0xce,0x7a,0xed,0xa2,0x3e, + 0xd5,0x9b,0xb8,0x8b,0x4f,0x02,0x03,0x01,0x00,0x01), chunk_from_chars( 0x06,0xad,0x82,0xc3,0x58,0x22,0xbb,0x79,0xb5,0xfc,0x48,0xdb,0xa0,0x3c,0x39,0x60, 0x00,0x85,0x06,0xca), @@ -351,6 +360,16 @@ static struct { 0xb8,0x9d,0x07,0x84,0x03,0x68,0x6b,0x9f,0xbf,0xe5,0xd8,0x14,0x2a,0xe0,0xef,0xbd, 0x1a,0x61,0x0d,0x3a,0xc8,0x67,0xcd,0x99,0x90,0xe3,0xe6,0x52,0x83,0x02,0x03,0x01, 0x00,0x01), + chunk_from_chars( + 0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xc0,0xbd,0x48,0x83,0xbc,0xea,0x0b,0x32,0x06, + 0x4b,0xf5,0x10,0x54,0x1b,0xba,0x88,0xc4,0x10,0x7e,0x47,0xec,0x0e,0xf9,0xb4,0xcf, + 0x9a,0x02,0xc6,0xb3,0xaf,0x35,0xc8,0xaf,0x78,0x1a,0xbc,0x37,0x1a,0x25,0x7a,0x37, + 0x24,0x73,0x53,0x9a,0xf0,0x44,0x64,0x5b,0x6b,0x64,0x4c,0xfa,0x83,0x3a,0x0f,0x77, + 0x5d,0x7b,0x21,0xa2,0x25,0x00,0x11,0xae,0x72,0x36,0x35,0xd9,0x0d,0xef,0x5a,0xdd, + 0x98,0x35,0x49,0xaf,0x44,0xa0,0x33,0x29,0xc0,0xca,0xf5,0x6f,0xfe,0xc1,0x06,0x4c, + 0x80,0x9a,0x54,0xbe,0x46,0x1a,0x96,0xb1,0xf3,0x29,0xb8,0x9d,0x07,0x84,0x03,0x68, + 0x6b,0x9f,0xbf,0xe5,0xd8,0x14,0x2a,0xe0,0xef,0xbd,0x1a,0x61,0x0d,0x3a,0xc8,0x67, + 0xcd,0x99,0x90,0xe3,0xe6,0x52,0x83,0x02,0x03,0x01,0x00,0x01), chunk_from_chars( 0xda,0xab,0x50,0x22,0x4b,0x4f,0x3b,0xd0,0x82,0xc4,0xa4,0x14,0x06,0x64,0x0b,0x6f, 0xad,0xbc,0x69,0xc0), @@ -491,6 +510,20 @@ static struct { 0x91,0xe2,0xfc,0x7b,0xea,0xb0,0x89,0x24,0xaa,0x00,0x29,0x8c,0x26,0x7c,0x94,0x54, 0x74,0xe4,0x11,0xa8,0x04,0x6f,0x40,0xeb,0xaf,0xed,0xac,0x75,0x33,0x02,0x03,0x01, 0x00,0x01), + chunk_from_chars( + 0x30,0x81,0xc9,0x02,0x81,0xc1,0x00,0xba,0xe3,0x37,0x93,0x7e,0x42,0x13,0x3c,0xba, + 0x41,0xc1,0x7b,0xf0,0xcc,0x7a,0x44,0xc6,0x54,0xc8,0x77,0x01,0x70,0x2f,0x6e,0x4a, + 0xcf,0x2d,0x07,0xab,0x01,0xc0,0x43,0xab,0x8d,0x33,0xb3,0xd4,0xeb,0xe3,0x90,0xf6, + 0x01,0x03,0x75,0x03,0x1d,0xe8,0x06,0x40,0x15,0xfa,0x96,0x0b,0xd5,0x26,0x64,0xea, + 0x55,0x82,0x16,0x7b,0xd5,0x1e,0xaa,0x08,0xc7,0x30,0x1a,0x59,0xf8,0xd9,0xe3,0x9e, + 0x89,0xd9,0x92,0x2c,0x32,0x79,0x0e,0xb3,0x25,0xbc,0x1d,0x7c,0x59,0xde,0x05,0x47, + 0x8f,0x61,0x77,0xf5,0x4f,0xed,0x82,0x2c,0xf8,0x2a,0x3e,0x02,0xf3,0xc0,0x15,0x51, + 0xde,0x05,0xc4,0xfc,0x80,0x91,0xae,0x06,0x1b,0xd7,0x39,0x8e,0x9a,0x6d,0xb3,0x2f, + 0xb0,0xd0,0xc8,0x96,0xa6,0x88,0xb3,0x17,0xca,0x58,0xbe,0x38,0x2c,0x64,0x35,0x5a, + 0x29,0xb7,0xf8,0x74,0x3d,0xbb,0xec,0x90,0x01,0x04,0x64,0x3d,0x38,0x0f,0x87,0xce, + 0xd7,0xfc,0xd2,0x96,0x93,0x31,0x85,0x0d,0x2d,0xa5,0x91,0xe2,0xfc,0x7b,0xea,0xb0, + 0x89,0x24,0xaa,0x00,0x29,0x8c,0x26,0x7c,0x94,0x54,0x74,0xe4,0x11,0xa8,0x04,0x6f, + 0x40,0xeb,0xaf,0xed,0xac,0x75,0x33,0x02,0x03,0x01,0x00,0x01), chunk_from_chars( 0x21,0x00,0x8c,0xe1,0x78,0x25,0x67,0x19,0xb7,0xd0,0xcb,0x13,0x01,0x7a,0xa3,0x71, 0x67,0x46,0x96,0xf1), @@ -671,6 +704,24 @@ static struct { 0xde,0x54,0x7d,0x95,0xd6,0x4e,0x58,0x12,0x06,0x60,0x22,0x33,0xf2,0x19,0x67,0x65, 0xdd,0xf3,0x42,0xb5,0x00,0x51,0x35,0xe5,0x62,0x4d,0x90,0x44,0xfb,0x7f,0x5b,0xb5, 0xe5,0x02,0x03,0x01,0x00,0x01), + chunk_from_chars( + 0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xba,0xbf,0x27,0x0b,0x22,0x59,0xd8, + 0x6f,0xff,0x26,0x5d,0x41,0x3d,0xb0,0x94,0x58,0x5d,0xc0,0x46,0xb6,0x77,0xa9,0x78, + 0x10,0x6d,0xe9,0xbf,0xca,0x6f,0x04,0xe1,0xda,0x85,0x12,0x1e,0xe0,0xa6,0xc7,0xa2, + 0x71,0x04,0x8b,0x6e,0x84,0xf9,0x86,0x2b,0xeb,0x72,0x01,0x72,0xc8,0x0a,0x83,0xa6, + 0xf7,0xc0,0xd6,0x76,0x1d,0x28,0x38,0xb5,0x7e,0x6c,0x8c,0x6a,0x13,0xf4,0xf1,0x7f, + 0xf2,0x79,0xae,0x73,0xba,0x1a,0x3f,0x30,0x65,0xb6,0x23,0xa7,0x94,0x34,0x29,0x87, + 0xce,0x06,0x99,0xee,0x85,0x10,0xce,0x08,0xe2,0x8d,0xd5,0x47,0xf3,0xc8,0xf0,0x18, + 0x41,0xc0,0x59,0x66,0x06,0xda,0xb6,0x18,0xd2,0xa3,0xa0,0xbd,0x3a,0x90,0x7f,0x37, + 0x39,0xdf,0x98,0x55,0xa2,0x19,0x5e,0x37,0xbc,0x86,0xf3,0x02,0xf8,0x68,0x49,0x53, + 0xf2,0x4b,0x3d,0x7a,0xe3,0x1d,0xa4,0x15,0x10,0xa6,0xce,0x8c,0xb8,0xfd,0x95,0x54, + 0xa2,0x50,0xa2,0xd9,0x35,0x12,0x56,0xae,0xbc,0x51,0x33,0x6d,0xb8,0x63,0x7c,0x26, + 0xab,0x19,0x01,0xa5,0xda,0xfa,0x4b,0xb6,0x57,0xd3,0x4b,0xdd,0xc0,0x62,0xc5,0x05, + 0xb7,0xc3,0x2e,0x1f,0x17,0xc8,0x09,0x87,0x12,0x37,0x21,0xd7,0x7a,0x53,0xb0,0x47, + 0x60,0xa2,0xb5,0x23,0x3b,0x99,0xdf,0xea,0x8b,0x94,0xea,0x9d,0x53,0x5d,0x02,0x52, + 0xf7,0x29,0xfb,0x63,0xb0,0xff,0x27,0x5e,0xde,0x54,0x7d,0x95,0xd6,0x4e,0x58,0x12, + 0x06,0x60,0x22,0x33,0xf2,0x19,0x67,0x65,0xdd,0xf3,0x42,0xb5,0x00,0x51,0x35,0xe5, + 0x62,0x4d,0x90,0x44,0xfb,0x7f,0x5b,0xb5,0xe5,0x02,0x03,0x01,0x00,0x01), chunk_from_chars( 0x4f,0xe8,0x82,0xee,0xaa,0x2c,0x7b,0x3f,0x3a,0xf1,0xb4,0xe1,0xe3,0x85,0xd4,0xb1, 0xb4,0x34,0x5c,0x2d), @@ -708,9 +759,17 @@ START_TEST(test_load) pubkey = privkey->get_public_key(privkey); ck_assert(pubkey != NULL); ck_assert(pubkey->get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &encoding)); - ck_assert_chunk_eq(keys[_i].pub, encoding); + ck_assert_chunk_eq(keys[_i].spki, encoding); chunk_free(&encoding); - + if (!pubkey->get_encoding(pubkey, PUBKEY_ASN1_DER, &encoding)) + { + warn("PUBKEY_ASN1_DER encoding not supported, ignored"); + } + else + { + ck_assert_chunk_eq(keys[_i].pub, encoding); + chunk_free(&encoding); + } ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp)); ck_assert_chunk_eq(keys[_i].fp_pk, fp); ck_assert(pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_INFO_SHA1, &fp));