Fix X509_PUBKEY_set() to show correct algorithm and parameters

When build with OpenSSL, trailing program outputs these messages.

algorithm: id-ecPublicKey
parameters: prime256v1

But with wolfSSL, X509_PUBKEY_get0_param() fails.
This patch fixes wolfSSL to display the same values as OpenSSL.

This program was extracted from wpa_supplicant in order to reproduce the
issue.

----------------
int main(void)
{
    EVP_PKEY *pkey;
    X509_PUBKEY *pub = NULL;
    ASN1_OBJECT *ppkalg, *poid;
    const ASN1_OBJECT *pa_oid;
    const uint8_t *pk;
    int ppklen, ptype;
    X509_ALGOR *pa;
    void *pval;
    char buf[100];
    const uint8_t data[] = {
        0x30, 0x39, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
        0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x22, 0x00, 0x03, 0x33, 0x6d, 0xb4, 0xe9, 0xab,
        0xf1, 0x1c, 0x96, 0x87, 0x5e, 0x02, 0xcc, 0x92, 0xaf, 0xf6, 0xe1, 0xed, 0x2b, 0xb2, 0xb7, 0xcc,
        0x3f, 0xd2, 0xb5, 0x4e, 0x6f, 0x20, 0xc7, 0xea, 0x2f, 0x3f, 0x42
    };
    size_t data_len = sizeof(data);
    const uint8_t *p;
    int res;

    p = data;
    pkey = d2i_PUBKEY(NULL, &p, data_len);
    if (!pkey) {
        fprintf(stderr, "d2i_PUBKEY() failed\n");
        return -1;
    }

    if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) {
        fprintf(stderr, "invalid type\n");
        EVP_PKEY_free(pkey);
        return -1;
    }

    res = X509_PUBKEY_set(&pub, pkey);
    if (res != 1) {
        fprintf(stderr, "X509_PUBKEY_set() failed\n");
        return -1;
    }

    res = X509_PUBKEY_get0_param(&ppkalg, &pk, &ppklen, &pa, pub);
    if (res != 1) {
        fprintf(stderr, "X509_PUBKEY_get0_param() failed\n");
        return -1;
    }
    res = OBJ_obj2txt(buf, sizeof(buf), ppkalg, 0);
    if (res < 0 || (size_t) res >= sizeof(buf)) {
        fprintf(stderr, "OBJ_obj2txt() failed\n");
        return -1;
    }
    fprintf(stdout, "algorithm: %s\n", buf);

    X509_ALGOR_get0(&pa_oid, &ptype, (void *) &pval, pa);
    if (ptype != V_ASN1_OBJECT) {
        fprintf(stderr, "X509_ALGOR_get0() failed\n");
        return -1;
    }
    poid = pval;
    res = OBJ_obj2txt(buf, sizeof(buf), poid, 0);
    if (res < 0 || (size_t) res >= sizeof(buf)) {
        fprintf(stderr, "OBJ_obj2txt() failed\n");
        return -1;
    }
    fprintf(stdout, "parameters: %s\n", buf);

    X509_PUBKEY_free(pub);
    EVP_PKEY_free(pkey);
    return 0;
}

Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
pull/4513/head
Masashi Honma 2021-11-09 07:30:58 +09:00
parent 4453001fac
commit ee39fd079f
3 changed files with 199 additions and 19 deletions

View File

@ -28947,8 +28947,8 @@ void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype,
if (paobj)
*paobj = algor->algorithm;
if (ppval)
*ppval = algor->algorithm;
if (ppval && algor->parameter)
*ppval = algor->parameter->value.ptr;
if (pptype) {
if (algor->parameter) {
*pptype = algor->parameter->type;
@ -28979,15 +28979,16 @@ int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj
if (aobj) {
algor->algorithm = aobj;
}
if (pval) {
if (!algor->parameter) {
algor->parameter = wolfSSL_ASN1_TYPE_new();
if (!algor->parameter) {
return WOLFSSL_FAILURE;
}
}
wolfSSL_ASN1_TYPE_set(algor->parameter, ptype, pval);
}
return WOLFSSL_SUCCESS;
}
@ -29000,10 +29001,16 @@ int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj
*/
void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value)
{
if (!a || !value) {
if (!a) {
return;
}
switch (type) {
case V_ASN1_NULL:
a->value.ptr = value;
break;
case V_ASN1_SEQUENCE:
a->value.asn1_string = (WOLFSSL_ASN1_STRING*)value;
break;
case V_ASN1_OBJECT:
a->value.object = (WOLFSSL_ASN1_OBJECT*)value;
break;
@ -29062,6 +29069,7 @@ void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at)
case V_ASN1_T61STRING:
case V_ASN1_IA5STRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_SEQUENCE:
wolfSSL_ASN1_STRING_free(at->value.asn1_string);
break;
default:
@ -29180,6 +29188,15 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key)
int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
{
WOLFSSL_X509_PUBKEY *pk = NULL;
int ptype;
void *pval;
#ifndef NO_DSA
WOLFSSL_ASN1_STRING *str;
#endif
#ifdef HAVE_ECC
int nid;
const WOLFSSL_EC_GROUP *group;
#endif
WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_set");
@ -29194,17 +29211,49 @@ int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
switch (key->type) {
#ifndef NO_RSA
case EVP_PKEY_RSA:
pk->algor->algorithm= wolfSSL_OBJ_nid2obj(NID_rsaEncryption);
pval = NULL;
ptype = V_ASN1_NULL;
pk->pubKeyOID = RSAk;
break;
#endif
#ifndef NO_DSA
case EVP_PKEY_DSA:
pk->algor->algorithm = wolfSSL_OBJ_nid2obj(NID_dsa);
if (!key->dsa->p || !key->dsa->q || !key->dsa->g)
goto error;
str = wolfSSL_ASN1_STRING_new();
if (str == NULL)
goto error;
str->length = wolfSSL_i2d_DSAparams(key->dsa, (unsigned char **)&str->data);
if (str->length <= 0)
goto error;
str->isDynamic = 1;
pval = str;
ptype = V_ASN1_SEQUENCE;
pk->pubKeyOID = DSAk;
break;
#endif
#ifdef HAVE_ECC
case EVP_PKEY_EC:
pk->algor->algorithm = wolfSSL_OBJ_nid2obj(NID_X9_62_id_ecPublicKey);
group = wolfSSL_EC_KEY_get0_group(key->ecc);
if (!group)
goto error;
nid = wolfSSL_EC_GROUP_get_curve_name(group);
if (nid == WOLFSSL_FAILURE) {
/* TODO: Add support for no nid case */
WOLFSSL_MSG("nid not found");
goto error;
}
pval = wolfSSL_OBJ_nid2obj(nid);
if (!pval)
goto error;
ptype = V_ASN1_OBJECT;
pk->pubKeyOID = ECDSAk;
break;
#endif
default:
@ -29212,8 +29261,12 @@ int wolfSSL_X509_PUBKEY_set(WOLFSSL_X509_PUBKEY **x, WOLFSSL_EVP_PKEY *key)
goto error;
}
if (!pk->algor->algorithm) {
if (!wolfSSL_X509_ALGOR_set0(pk->algor, wolfSSL_OBJ_nid2obj(key->type), ptype, pval)) {
WOLFSSL_MSG("Failed to create algorithm object");
if (ptype == V_ASN1_OBJECT)
ASN1_OBJECT_free(pval);
else
ASN1_STRING_free(pval);
goto error;
}

View File

@ -36240,7 +36240,7 @@ static void test_wolfSSL_X509_ALGOR_get0(void)
/* Valid case */
X509_ALGOR_get0(&obj, &pptype, &ppval, alg);
AssertNotNull(obj);
AssertNotNull(ppval);
AssertNull(ppval);
AssertIntNE(pptype, 0);
/* Make sure NID of X509_ALGOR is Sha256 with RSA */
AssertIntEQ(OBJ_obj2nid(obj), NID_sha256WithRSAEncryption);
@ -36408,21 +36408,23 @@ static void test_wolfSSL_X509_get_X509_PUBKEY(void)
#endif
}
static void test_wolfSSL_X509_PUBKEY(void)
static void test_wolfSSL_X509_PUBKEY_RSA(void)
{
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && \
!defined(NO_SHA256) && !defined(NO_RSA)
X509* x509 = NULL;
ASN1_OBJECT* obj = NULL;
const ASN1_OBJECT* pa_oid = NULL;
X509_PUBKEY* pubKey;
X509_PUBKEY* pubKey2;
EVP_PKEY* evpKey;
const unsigned char *pk;
int ppklen;
WOLFSSL_X509_ALGOR *pa;
int ppklen, pptype;
X509_ALGOR *pa;
const void *pval;
printf(testingFmt, "wolfSSL_X509_get_X509_PUBKEY");
printf(testingFmt, "wolfSSL_X509_PUBKEY_RSA");
AssertNotNull(x509 = X509_load_certificate_file(cliCertFile,
SSL_FILETYPE_PEM));
@ -36439,6 +36441,15 @@ static void test_wolfSSL_X509_PUBKEY(void)
AssertNotNull(evpKey = X509_PUBKEY_get(pubKey));
AssertNotNull(pubKey2 = X509_PUBKEY_new());
AssertIntEQ(X509_PUBKEY_set(&pubKey2, evpKey), 1);
AssertIntEQ(X509_PUBKEY_get0_param(&obj, &pk, &ppklen, &pa, pubKey2), 1);
AssertNotNull(pk);
AssertNotNull(pa);
AssertIntGT(ppklen, 0);
X509_ALGOR_get0(&pa_oid, &pptype, &pval, pa);
AssertNotNull(pa_oid);
AssertNull(pval);
AssertIntEQ(pptype, V_ASN1_NULL);
AssertIntEQ(OBJ_obj2nid(pa_oid), EVP_PKEY_RSA);
X509_PUBKEY_free(pubKey2);
X509_free(x509);
@ -36448,6 +36459,119 @@ static void test_wolfSSL_X509_PUBKEY(void)
#endif
}
static void test_wolfSSL_X509_PUBKEY_EC(void)
{
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && defined(HAVE_ECC)
X509* x509 = NULL;
ASN1_OBJECT* obj = NULL;
ASN1_OBJECT* poid;
const ASN1_OBJECT* pa_oid = NULL;
X509_PUBKEY* pubKey;
X509_PUBKEY* pubKey2;
EVP_PKEY* evpKey;
const unsigned char *pk;
int ppklen, pptype;
X509_ALGOR *pa;
const void *pval;
char buf[50];
printf(testingFmt, "wolfSSL_X509_PUBKEY_EC");
AssertNotNull(x509 = X509_load_certificate_file(cliEccCertFile,
SSL_FILETYPE_PEM));
AssertNotNull(pubKey = X509_get_X509_PUBKEY(x509));
AssertNotNull(evpKey = X509_PUBKEY_get(pubKey));
AssertNotNull(pubKey2 = X509_PUBKEY_new());
AssertIntEQ(X509_PUBKEY_set(&pubKey2, evpKey), 1);
AssertIntEQ(X509_PUBKEY_get0_param(&obj, &pk, &ppklen, &pa, pubKey2), 1);
AssertNotNull(pk);
AssertNotNull(pa);
AssertIntGT(ppklen, 0);
X509_ALGOR_get0(&pa_oid, &pptype, &pval, pa);
AssertNotNull(pa_oid);
AssertNotNull(pval);
AssertIntEQ(pptype, V_ASN1_OBJECT);
AssertIntEQ(OBJ_obj2nid(pa_oid), EVP_PKEY_EC);
poid = (ASN1_OBJECT *)pval;
AssertIntGT(OBJ_obj2txt(buf, (int)sizeof(buf), poid, 0), 0);
AssertIntEQ(OBJ_txt2nid(buf), NID_X9_62_prime256v1);
X509_PUBKEY_free(pubKey2);
X509_free(x509);
EVP_PKEY_free(evpKey);
printf(resultFmt, passed);
#endif
}
static void test_wolfSSL_X509_PUBKEY_DSA(void)
{
#if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) && !defined(NO_DSA)
word32 bytes;
#ifdef USE_CERT_BUFFERS_1024
byte tmp[ONEK_BUF];
XMEMSET(tmp, 0, sizeof(tmp));
XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024);
bytes = sizeof_dsa_key_der_1024;
#elif defined(USE_CERT_BUFFERS_2048)
byte tmp[TWOK_BUF];
XMEMSET(tmp, 0, sizeof(tmp));
XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048);
bytes = sizeof_dsa_key_der_2048;
#else
byte tmp[TWOK_BUF];
XMEMSET(tmp, 0, sizeof(tmp));
XFILE fp = XFOPEN("./certs/dsa2048.der", "rb");
if (fp == XBADFILE) {
return WOLFSSL_BAD_FILE;
}
bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), fp);
XFCLOSE(fp);
#endif /* END USE_CERT_BUFFERS_1024 */
const unsigned char* dsaKeyDer = tmp;
ASN1_OBJECT* obj = NULL;
ASN1_STRING* str;
const ASN1_OBJECT* pa_oid = NULL;
X509_PUBKEY* pubKey = NULL;
EVP_PKEY* evpKey = NULL;
const unsigned char *pk;
int ppklen, pptype;
X509_ALGOR *pa;
const void *pval;
printf(testingFmt, "wolfSSL_X509_PUBKEY_DSA");
/* Initialize pkey with der format dsa key */
AssertNotNull(d2i_PrivateKey(EVP_PKEY_DSA, &evpKey, &dsaKeyDer, bytes));
AssertNotNull(pubKey = X509_PUBKEY_new());
AssertIntEQ(X509_PUBKEY_set(&pubKey, evpKey), 1);
AssertIntEQ(X509_PUBKEY_get0_param(&obj, &pk, &ppklen, &pa, pubKey), 1);
AssertNotNull(pk);
AssertNotNull(pa);
AssertIntGT(ppklen, 0);
X509_ALGOR_get0(&pa_oid, &pptype, &pval, pa);
AssertNotNull(pa_oid);
AssertNotNull(pval);
AssertIntEQ(pptype, V_ASN1_SEQUENCE);
AssertIntEQ(OBJ_obj2nid(pa_oid), EVP_PKEY_DSA);
str = (ASN1_STRING *)pval;
#ifdef USE_CERT_BUFFERS_1024
AssertIntEQ(ASN1_STRING_length(str), 291);
#else
AssertIntEQ(ASN1_STRING_length(str), 549);
#endif /* END USE_CERT_BUFFERS_1024 */
X509_PUBKEY_free(pubKey);
EVP_PKEY_free(evpKey);
printf(resultFmt, passed);
#endif
}
static void test_wolfSSL_RAND(void)
{
#if defined(OPENSSL_EXTRA)
@ -51666,7 +51790,9 @@ void ApiTest(void)
test_wolfSSL_X509_get0_tbs_sigalg();
test_wolfSSL_X509_ALGOR_get0();
test_wolfSSL_X509_get_X509_PUBKEY();
test_wolfSSL_X509_PUBKEY();
test_wolfSSL_X509_PUBKEY_RSA();
test_wolfSSL_X509_PUBKEY_EC();
test_wolfSSL_X509_PUBKEY_DSA();
test_wolfSSL_RAND();
test_wolfSSL_BUF();
test_wolfSSL_set_tlsext_status_type();

View File

@ -71,6 +71,7 @@
#define ASN1_TIME_set wolfSSL_ASN1_TIME_set
#define V_ASN1_EOC 0
#define V_ASN1_NULL 5
#define V_ASN1_OBJECT 6
#define V_ASN1_UTF8STRING 12
#define V_ASN1_SEQUENCE 16