From 2bae1d27a1fdb5091aec5210145c994bc12e4486 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 15 Oct 2019 11:17:51 -0700 Subject: [PATCH] wolfSSL Compatibility support for OpenVPN * Adds compatibility API's for: * `sk_ASN1_OBJECT_free` * `sk_ASN1_OBJECT_num` * `sk_ASN1_OBJECT_value` * `sk_X509_OBJECT_num` * `sk_X509_OBJECT_value` * `sk_X509_OBJECT_delete` * `sk_X509_NAME_find` * `sk_X509_INFO_free` * `BIO_get_len` * `BIO_set_ssl` * `BIO_should_retry` (stub) * `X509_OBJECT_free` * `X509_NAME_get_index_by_OBJ` * `X509_INFO_free` * `X509_STORE_get0_objects` * `X509_check_purpose` (stub) * `PEM_read_bio_X509_CRL` * `PEM_X509_INFO_read_bio` * `ASN1_BIT_STRING_new` * `ASN1_BIT_STRING_free` * `ASN1_BIT_STRING_get_bit` * `ASN1_BIT_STRING_set_bit` * `DES_check_key_parity` * `EC_GROUP_order_bits` * `EC_get_builtin_curves` * `EVP_CIPHER_CTX_cipher` * `EVP_PKEY_get0_EC_KEY` * `EVP_PKEY_get0_RSA` * `EVP_PKEY_get0_DSA` (stub) * `HMAC_CTX_new` * `HMAC_CTX_free` * `HMAC_CTX_reset` * `HMAC_size` * `OBJ_txt2obj` * `RSA_meth_new` * `RSA_meth_free` * `RSA_meth_set_pub_enc` * `RSA_meth_set_pub_dec` * `RSA_meth_set_priv_enc` * `RSA_meth_set_priv_dec` * `RSA_meth_set_init` * `RSA_meth_set_finish` * `RSA_meth_set0_app_data` * `RSA_get_method_data` * `RSA_set_method` * `RSA_get0_key` * `RSA_set0_key` * `RSA_flags` * `RSA_set_flags` * `RSA_bits` * `SSL_CTX_set_ciphersuites` * `SSL_CTX_set_security_level` (stub) * `SSL_export_keying_material` (stub) * `DSA_bits` (stub) * Changes to support password callback trial and NO_PASSWORD. Replaces PR #2505. * Renamed `wolfSSL_SSL_CTX_get_client_CA_list` to `wolfSSL_CTX_get_client_CA_list`. * Cleanup of "sk" compatibility. --- .gitignore | 3 +- certs/client-cert-ext.der | Bin 0 -> 1292 bytes certs/client-cert-ext.pem | 93 ++ certs/include.am | 7 +- certs/renewcerts/wolfssl.cnf | 1 + src/bio.c | 36 + src/ssl.c | 2339 +++++++++++++++++++++------------- tests/api.c | 559 ++++++-- tests/unit.h | 13 + wolfcrypt/src/evp.c | 50 +- wolfssl/internal.h | 4 +- wolfssl/openssl/bio.h | 2 + wolfssl/openssl/buffer.h | 4 - wolfssl/openssl/crypto.h | 2 - wolfssl/openssl/des.h | 2 + wolfssl/openssl/ec.h | 17 + wolfssl/openssl/err.h | 19 + wolfssl/openssl/evp.h | 21 +- wolfssl/openssl/hmac.h | 7 + wolfssl/openssl/include.am | 1 + wolfssl/openssl/rsa.h | 52 +- wolfssl/openssl/ssl.h | 52 +- wolfssl/openssl/stack.h | 12 +- wolfssl/openssl/tls1.h | 46 + wolfssl/openssl/x509.h | 3 + wolfssl/openssl/x509v3.h | 24 +- wolfssl/ssl.h | 69 +- wolfssl/test.h | 4 + wolfssl/wolfcrypt/asn.h | 4 +- 29 files changed, 2376 insertions(+), 1070 deletions(-) create mode 100644 certs/client-cert-ext.der create mode 100644 certs/client-cert-ext.pem create mode 100644 wolfssl/openssl/tls1.h diff --git a/.gitignore b/.gitignore index 557539c95..d8c0423d5 100644 --- a/.gitignore +++ b/.gitignore @@ -324,10 +324,11 @@ doc/pdf # XCODE Index IDE/XCODE/Index -# ARM DS-5 +# ARM DS-5 && Eclipse \.settings/ \.cproject \.project +\.autotools # Renesas e2studio /IDE/Renesas/e2studio/Projects/test/src/smc_gen diff --git a/certs/client-cert-ext.der b/certs/client-cert-ext.der new file mode 100644 index 0000000000000000000000000000000000000000..d58a1dbf33744db35bd898c13de4ad04341f6998 GIT binary patch literal 1292 zcmXqLV&yPsV*apznTe5!Nu=)oF(?1#Zh5J>e)_xA=TE=>=+$ZiUN%mxHjlRNyo`+8 ztPBQ?^9;ESIN6v(S=fY`LW2zj4ER7C4jy*j{JfIHyhNA?I}f{4epPC2VxFO>fiOr7 z7Y|Q)eok6&uur^^fr*8oq=7g{n43o+peR4RC^0uTGcR2iEG1ze29jdt;V&;Q*8}M) zF3!`q*KYc~=@e{_18d>Q3Liu=IqPj@KpW@7=r3^ZtDQ=3}E=^=xMMS^HDZ z)TgRsE_)%;8U4iM`_T;|lfR}{TUAv&WDElL`2MUIxFZ!v1h?`=EO;V{#zd6%3+k&^iJpj4IO z4d>oVo?Z99BB%O*5c3tkBHn;p>&4cKXU5Gvag(QY^UbcCA!@gCf34a5U)ATx#mX;* zm)jg9gf}E_E%GxsGQFiuH%$M!==b^q>%RVpe)@aiuFFi!j0}v6n;5MOni$OtWZ9TQ zW%*ddSVW9(xTamtXqTu9;Vn>~cwFszYw7`m#(N-nWtPTk291{+u&Pzx6L)GwVs1fBDk#^0^QbI8BjbM-7G@^KHstih z4NhN-3~q;(E;DM`kiqPD&-~Wm9d3nIhO4ALG-@1XH%}C=6>xp`{_Fus{drRvW3O=v z_es9GrCyq*_;Bx!=?k`Y&npyGD-AIDx~A{P<<9FtT%Y3Y*bgy1Fe@%KSQ)iT<^69B z4qn6H7TdqFlYWZcVysapxVnw^mDR`A2^$Y@FH|_qtn|76DU<)ka+&GkI@T{8r6g)P zZ}!ETto*w7eukdN8NusM&&}`RZJQ$6_RENWg2YAL`(j}coT?KQ4_*FNcfxZO z!}Y}Db1x}xte>`_GOwG{LSOiy$Glk@S2$dXHG@1~&;7mZhrHg=%Z5R1uOw#57O(dH ST$BH`g>` literal 0 HcmV?d00001 diff --git a/certs/client-cert-ext.pem b/certs/client-cert-ext.pem new file mode 100644 index 000000000..b50da7104 --- /dev/null +++ b/certs/client-cert-ext.pem @@ -0,0 +1,93 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 7e:ff:c6:42:4f:83:8b:1f:1a:9d:4e:2f:ba:27:9f:97:d7:e2:ea:ab + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Sep 20 14:13:15 2019 GMT + Not After : Jun 16 14:13:15 2022 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:c3:03:d1:2b:fe:39:a4:32:45:3b:53:c8:84:2b: + 2a:7c:74:9a:bd:aa:2a:52:07:47:d6:a6:36:b2:07: + 32:8e:d0:ba:69:7b:c6:c3:44:9e:d4:81:48:fd:2d: + 68:a2:8b:67:bb:a1:75:c8:36:2c:4a:d2:1b:f7:8b: + ba:cf:0d:f9:ef:ec:f1:81:1e:7b:9b:03:47:9a:bf: + 65:cc:7f:65:24:69:a6:e8:14:89:5b:e4:34:f7:c5: + b0:14:93:f5:67:7b:3a:7a:78:e1:01:56:56:91:a6: + 13:42:8d:d2:3c:40:9c:4c:ef:d1:86:df:37:51:1b: + 0c:a1:3b:f5:f1:a3:4a:35:e4:e1:ce:96:df:1b:7e: + bf:4e:97:d0:10:e8:a8:08:30:81:af:20:0b:43:14: + c5:74:67:b4:32:82:6f:8d:86:c2:88:40:99:36:83: + ba:1e:40:72:22:17:d7:52:65:24:73:b0:ce:ef:19: + cd:ae:ff:78:6c:7b:c0:12:03:d4:4e:72:0d:50:6d: + 3b:a3:3b:a3:99:5e:9d:c8:d9:0c:85:b3:d9:8a:d9: + 54:26:db:6d:fa:ac:bb:ff:25:4c:c4:d1:79:f4:71: + d3:86:40:18:13:b0:63:b5:72:4e:30:c4:97:84:86: + 2d:56:2f:d7:15:f7:7f:c0:ae:f5:fc:5b:e5:fb:a1: + ba:d3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 33:D8:45:66:D7:68:87:18:7E:54:0D:70:27:91:C7:26:D7:85:65:C0 + X509v3 Authority Key Identifier: + keyid:33:D8:45:66:D7:68:87:18:7E:54:0D:70:27:91:C7:26:D7:85:65:C0 + DirName:/C=US/ST=Montana/L=Bozeman/O=wolfSSL_2048/OU=Programming-2048/CN=www.wolfssl.com/emailAddress=info@wolfssl.com + serial:7E:FF:C6:42:4F:83:8B:1F:1A:9D:4E:2F:BA:27:9F:97:D7:E2:EA:AB + + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Alternative Name: + DNS:example.com + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Signature Algorithm: sha256WithRSAEncryption + 46:c2:a5:a6:32:84:b0:68:03:41:de:37:da:c3:b8:46:71:3a: + 31:aa:1a:f0:81:28:c3:07:37:61:17:7d:10:45:ee:ef:cd:c0: + 19:2f:9e:95:01:5d:d6:09:13:8e:19:ea:da:27:75:66:21:e1: + bd:f8:97:a0:b5:8b:9e:71:13:26:75:50:34:f5:ac:8e:f8:d3: + 89:d7:52:0a:f2:5f:3e:07:c2:02:e0:36:73:75:30:a9:5a:ba: + 24:ef:fb:28:08:0d:31:53:84:3d:fd:1d:92:f9:15:da:01:7c: + 20:70:d5:b6:0d:ea:3a:f1:85:90:b1:c3:b7:71:20:cb:03:22: + f3:8f:e5:02:4f:b1:77:1c:97:17:2c:3b:e9:41:1a:18:7c:89: + d9:8e:5f:34:6c:66:9c:61:79:f5:bd:df:68:2e:14:cc:11:d7: + e5:ce:9f:8a:0d:86:94:15:86:fa:32:0f:90:18:d1:2d:df:16: + 56:58:09:25:91:21:c2:d3:f6:7e:c8:49:aa:00:d7:61:c7:9d: + d2:23:b1:7f:96:b0:79:6e:8b:09:38:2f:13:e1:48:9e:9a:28: + d4:08:44:73:29:52:49:eb:9d:fb:a6:f8:1f:2e:c5:d3:31:52: + 86:ea:18:99:1d:73:ab:4b:f3:7c:6f:f5:84:c3:96:fb:02:36: + d9:13:64:8b +-----BEGIN CERTIFICATE----- +MIIFCDCCA/CgAwIBAgIUfv/GQk+Dix8anU4vuiefl9fi6qswDQYJKoZIhvcNAQEL +BQAwgZ4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdC +b3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIwNDgxGTAXBgNVBAsMEFByb2dyYW1t +aW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJ +ARYQaW5mb0B3b2xmc3NsLmNvbTAeFw0xOTA5MjAxNDEzMTVaFw0yMjA2MTYxNDEz +MTVaMIGeMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwH +Qm96ZW1hbjEVMBMGA1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFt +bWluZy0yMDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0B +CQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDDA9Er/jmkMkU7U8iEKyp8dJq9qipSB0fWpjayBzKO0Lppe8bDRJ7UgUj9 +LWiii2e7oXXINixK0hv3i7rPDfnv7PGBHnubA0eav2XMf2UkaaboFIlb5DT3xbAU +k/Vnezp6eOEBVlaRphNCjdI8QJxM79GG3zdRGwyhO/Xxo0o15OHOlt8bfr9Ol9AQ +6KgIMIGvIAtDFMV0Z7Qygm+NhsKIQJk2g7oeQHIiF9dSZSRzsM7vGc2u/3hse8AS +A9ROcg1QbTujO6OZXp3I2QyFs9mK2VQm2236rLv/JUzE0Xn0cdOGQBgTsGO1ck4w +xJeEhi1WL9cV93/ArvX8W+X7obrTAgMBAAGjggE6MIIBNjAdBgNVHQ4EFgQUM9hF +Ztdohxh+VA1wJ5HHJteFZcAwgd4GA1UdIwSB1jCB04AUM9hFZtdohxh+VA1wJ5HH +JteFZcChgaSkgaEwgZ4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAw +DgYDVQQHDAdCb3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIwNDgxGTAXBgNVBAsM +EFByb2dyYW1taW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0G +CSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbYIUfv/GQk+Dix8anU4vuiefl9fi +6qswDAYDVR0TBAUwAwEB/zAWBgNVHREEDzANggtleGFtcGxlLmNvbTAOBgNVHQ8B +Af8EBAMCAYYwDQYJKoZIhvcNAQELBQADggEBAEbCpaYyhLBoA0HeN9rDuEZxOjGq +GvCBKMMHN2EXfRBF7u/NwBkvnpUBXdYJE44Z6tondWYh4b34l6C1i55xEyZ1UDT1 +rI7404nXUgryXz4HwgLgNnN1MKlauiTv+ygIDTFThD39HZL5FdoBfCBw1bYN6jrx +hZCxw7dxIMsDIvOP5QJPsXcclxcsO+lBGhh8idmOXzRsZpxhefW932guFMwR1+XO +n4oNhpQVhvoyD5AY0S3fFlZYCSWRIcLT9n7ISaoA12HHndIjsX+WsHluiwk4LxPh +SJ6aKNQIRHMpUknrnfum+B8uxdMxUobqGJkdc6tL83xv9YTDlvsCNtkTZIs= +-----END CERTIFICATE----- diff --git a/certs/include.am b/certs/include.am index 43c6bcfd6..a3db1baca 100644 --- a/certs/include.am +++ b/certs/include.am @@ -51,7 +51,9 @@ EXTRA_DIST += \ certs/ecc-privOnlyCert.pem \ certs/dh3072.pem \ certs/client-cert-3072.pem \ - certs/client-key-3072.pem + certs/client-key-3072.pem \ + certs/client-cert-ext.pem + EXTRA_DIST += \ certs/ca-key.der \ certs/ca-cert.der \ @@ -75,7 +77,8 @@ EXTRA_DIST += \ certs/server-ecc.der \ certs/server-ecc-self.der \ certs/server-ecc-rsa.der \ - certs/server-cert-chain.der + certs/server-cert-chain.der \ + certs/client-cert-ext.der # ECC CA prime256v1 EXTRA_DIST += \ diff --git a/certs/renewcerts/wolfssl.cnf b/certs/renewcerts/wolfssl.cnf index da9752c5b..54a8cf0cc 100644 --- a/certs/renewcerts/wolfssl.cnf +++ b/certs/renewcerts/wolfssl.cnf @@ -124,6 +124,7 @@ authorityKeyIdentifier=keyid,issuer subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer:always basicConstraints=CA:true +subjectAltName=DNS:example.com #wolfssl extensions for intermediate CAs [wolfssl_opts_ICA] diff --git a/src/bio.c b/src/bio.c index 2d740de77..6083297ac 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1306,6 +1306,42 @@ long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) return 0; } +int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio) +{ + int len; +#ifndef NO_FILESYSTEM + long memSz; + XFILE file; + long curr = 0; +#endif + + WOLFSSL_ENTER("wolfSSL_BIO_get_len"); + + if ((len = wolfSSL_BIO_pending(bio)) > 0) { + } +#ifndef NO_FILESYSTEM + else if (bio->type == WOLFSSL_BIO_FILE) { + if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS) + len = BAD_FUNC_ARG; + if (len == 0) { + curr = XFTELL(file); + if (curr < 0) { + len = WOLFSSL_BAD_FILE; + } + if (XFSEEK(file, 0, XSEEK_END) != 0) + len = WOLFSSL_BAD_FILE; + } + if (len == 0) { + memSz = XFTELL(file) - curr; + len = (int)memSz; + if (XFSEEK(file, curr, SEEK_SET) != 0) + len = WOLFSSL_BAD_FILE; + } + } +#endif + return len; +} + void wolfSSL_BIO_set_callback(WOLFSSL_BIO *bio, wolf_bio_info_cb callback_func) { diff --git a/src/ssl.c b/src/ssl.c index bdd71e9a2..96fd370f9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -31,7 +31,8 @@ #define _GNU_SOURCE #endif -#if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) +#if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) || \ + defined(OPENSSL_EXTRA_X509_SMALL) #ifdef HAVE_ERRNO_H #include @@ -3497,69 +3498,105 @@ int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm) static const struct cipher{ unsigned char type; const char *name; + int nid; } cipher_tbl[] = { #ifndef NO_AES #ifdef WOLFSSL_AES_128 - {AES_128_CBC_TYPE, "AES-128-CBC"}, + {AES_128_CBC_TYPE, "AES-128-CBC", NID_aes_128_cbc}, #endif #ifdef WOLFSSL_AES_192 - {AES_192_CBC_TYPE, "AES-192-CBC"}, + {AES_192_CBC_TYPE, "AES-192-CBC", NID_aes_192_cbc}, #endif #ifdef WOLFSSL_AES_256 - {AES_256_CBC_TYPE, "AES-256-CBC"}, + {AES_256_CBC_TYPE, "AES-256-CBC", NID_aes_256_cbc}, #endif #if defined(OPENSSL_EXTRA) #ifdef WOLFSSL_AES_128 - {AES_128_GCM_TYPE, "AES-128-GCM"}, + {AES_128_GCM_TYPE, "AES-128-GCM", NID_aes_128_gcm}, #endif #ifdef WOLFSSL_AES_192 - {AES_192_GCM_TYPE, "AES-192-GCM"}, + {AES_192_GCM_TYPE, "AES-192-GCM", NID_aes_192_gcm}, #endif #ifdef WOLFSSL_AES_256 - {AES_256_GCM_TYPE, "AES-256-GCM"}, + {AES_256_GCM_TYPE, "AES-256-GCM", NID_aes_256_gcm}, #endif #ifdef WOLFSSL_AES_128 - {AES_128_CTR_TYPE, "AES-128-CTR"}, + {AES_128_CTR_TYPE, "AES-128-CTR", NID_aes_128_ctr}, #endif #ifdef WOLFSSL_AES_192 - {AES_192_CTR_TYPE, "AES-192-CTR"}, + {AES_192_CTR_TYPE, "AES-192-CTR", NID_aes_192_ctr}, #endif #ifdef WOLFSSL_AES_256 - {AES_256_CTR_TYPE, "AES-256-CTR"}, + {AES_256_CTR_TYPE, "AES-256-CTR", NID_aes_256_ctr}, #endif #ifdef WOLFSSL_AES_128 - {AES_128_ECB_TYPE, "AES-128-ECB"}, + {AES_128_ECB_TYPE, "AES-128-ECB", NID_aes_128_ecb}, #endif #ifdef WOLFSSL_AES_192 - {AES_192_ECB_TYPE, "AES-192-ECB"}, + {AES_192_ECB_TYPE, "AES-192-ECB", NID_aes_192_ecb}, #endif #ifdef WOLFSSL_AES_256 - {AES_256_ECB_TYPE, "AES-256-ECB"}, + {AES_256_ECB_TYPE, "AES-256-ECB", NID_aes_256_ecb}, #endif #endif #endif #ifndef NO_DES3 - {DES_CBC_TYPE, "DES-CBC"}, - {DES_ECB_TYPE, "DES-ECB"}, + {DES_CBC_TYPE, "DES-CBC", NID_des_cbc}, + {DES_ECB_TYPE, "DES-ECB", NID_des_ecb}, - {DES_EDE3_CBC_TYPE, "DES-EDE3-CBC"}, - {DES_EDE3_ECB_TYPE, "DES-EDE3-ECB"}, + {DES_EDE3_CBC_TYPE, "DES-EDE3-CBC", NID_des_ede3_cbc}, + {DES_EDE3_ECB_TYPE, "DES-EDE3-ECB", NID_des_ede3_ecb}, #endif #ifndef NO_RC4 - {ARC4_TYPE, "ARC4"}, + {ARC4_TYPE, "ARC4", NID_undef}, #endif #ifdef HAVE_IDEA - {IDEA_CBC_TYPE, "IDEA-CBC"}, + {IDEA_CBC_TYPE, "IDEA-CBC", NID_idea_cbc}, #endif - { 0, NULL} + { 0, NULL, 0} }; +const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_CIPHER_CTX_cipher( + const WOLFSSL_EVP_CIPHER_CTX *ctx) +{ + const struct cipher* c; + + if (!ctx || !ctx->cipherType) { + return NULL; + } + + for (c = cipher_tbl; c->type != 0; c++) { + if (ctx->cipherType == c->type) { + return wolfSSL_EVP_get_cipherbyname(c->name); + } + } + + return NULL; +} + +int wolfSSL_EVP_CIPHER_nid(const WOLFSSL_EVP_CIPHER *cipher) +{ + const struct cipher* c; + + if (!cipher) { + return 0; + } + + for (c = cipher_tbl; c->type != 0; c++) { + if (XSTRNCMP(cipher, c->name, XSTRLEN(c->name)+1) == 0) { + return c->nid; + } + } + + return 0; +} + const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name) { @@ -4936,6 +4973,199 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff, return ret; } +static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der, + int* keySz, word32* idx, int* resetSuites, int *rsaKey, int *eccKey, + int *ed25519Key, void* heap, int devId) +{ + int ret = 0; + + if (ctx == NULL && ssl == NULL) + return BAD_FUNC_ARG; + if (!der || !keySz || !idx || !resetSuites || !rsaKey || !eccKey || !ed25519Key) + return BAD_FUNC_ARG; + +#ifndef NO_RSA + if (ret == 0 && !*eccKey && !*ed25519Key) { + /* make sure RSA key can be used */ + #ifdef WOLFSSL_SMALL_STACK + RsaKey* key = NULL; + #else + RsaKey key[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA); + if (key == NULL) + return MEMORY_E; + #endif + + ret = wc_InitRsaKey_ex(key, heap, devId); + if (ret == 0) { + *idx = 0; + if (wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length) + != 0) { + #ifdef HAVE_ECC + /* could have DER ECC (or pkcs8 ecc), no easy way to tell */ + *eccKey = 1; /* try it next */ + #elif defined(HAVE_ED25519) + *ed25519Key = 1; /* try it next */ + #else + WOLFSSL_MSG("RSA decode failed and ECC not enabled to try"); + ret = WOLFSSL_BAD_FILE; + #endif + } + else { + /* check that the size of the RSA key is enough */ + int minRsaSz = ssl ? ssl->options.minRsaKeySz : + ctx->minRsaKeySz; + *keySz = wc_RsaEncryptSize((RsaKey*)key); + if (*keySz < minRsaSz) { + ret = RSA_KEY_SIZE_E; + WOLFSSL_MSG("Private Key size too small"); + } + + if (ssl) { + ssl->buffers.keyType = rsa_sa_algo; + ssl->buffers.keySz = *keySz; + } + else if(ctx) { + ctx->privateKeyType = rsa_sa_algo; + ctx->privateKeySz = *keySz; + } + + *rsaKey = 1; + (void)rsaKey; /* for no ecc builds */ + + if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { + ssl->options.haveStaticECC = 0; + *resetSuites = 1; + } + } + + wc_FreeRsaKey(key); + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(key, heap, DYNAMIC_TYPE_RSA); + #endif + } +#endif +#ifdef HAVE_ECC + if (ret == 0 && !*rsaKey && !*ed25519Key) { + /* make sure ECC key can be used */ + #ifdef WOLFSSL_SMALL_STACK + ecc_key* key = NULL; + #else + ecc_key key[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC); + if (key == NULL) + return MEMORY_E; + #endif + + if (wc_ecc_init_ex(key, heap, devId) == 0) { + *idx = 0; + if (wc_EccPrivateKeyDecode(der->buffer, idx, key, + der->length) == 0) { + /* check for minimum ECC key size and then free */ + int minKeySz = ssl ? ssl->options.minEccKeySz : + ctx->minEccKeySz; + *keySz = wc_ecc_size(key); + if (*keySz < minKeySz) { + WOLFSSL_MSG("ECC private key too small"); + ret = ECC_KEY_SIZE_E; + } + + *eccKey = 1; + if (ssl) { + ssl->options.haveStaticECC = 1; + ssl->buffers.keyType = ecc_dsa_sa_algo; + ssl->buffers.keySz = *keySz; + } + else if (ctx) { + ctx->haveStaticECC = 1; + ctx->privateKeyType = ecc_dsa_sa_algo; + ctx->privateKeySz = *keySz; + } + + if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { + *resetSuites = 1; + } + } + else + *eccKey = 0; + + wc_ecc_free(key); + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(key, heap, DYNAMIC_TYPE_ECC); + #endif + } +#endif /* HAVE_ECC */ +#ifdef HAVE_ED25519 + if (ret == 0 && !*rsaKey && !*eccKey) { + /* make sure Ed25519 key can be used */ + #ifdef WOLFSSL_SMALL_STACK + ed25519_key* key = NULL; + #else + ed25519_key key[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap, + DYNAMIC_TYPE_ED25519); + if (key == NULL) + return MEMORY_E; + #endif + + ret = wc_ed25519_init(key); + if (ret == 0) { + *idx = 0; + if (wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, + der->length) != 0) { + ret = WOLFSSL_BAD_FILE; + } + + if (ret == 0) { + /* check for minimum key size and then free */ + int minKeySz = ssl ? ssl->options.minEccKeySz : + ctx->minEccKeySz; + *keySz = ED25519_KEY_SIZE; + if (*keySz < minKeySz) { + WOLFSSL_MSG("ED25519 private key too small"); + ret = ECC_KEY_SIZE_E; + } + } + if (ret == 0) { + if (ssl) { + ssl->buffers.keyType = ed25519_sa_algo; + ssl->buffers.keySz = *keySz; + } + else if (ctx) { + ctx->privateKeyType = ed25519_sa_algo; + ctx->privateKeySz = *keySz; + } + + *ed25519Key = 1; + if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { + *resetSuites = 1; + } + } + + wc_ed25519_free(key); + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(key, heap, DYNAMIC_TYPE_ED25519); + #endif + } +#endif /* HAVE_ED25519 */ + return ret; +} + /* process the buffer buff, length sz, into ctx of format and type used tracks bytes consumed, userChain specifies a user cert chain to pass during the handshake */ @@ -5052,51 +5282,12 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } } -#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED) - /* for WOLFSSL_FILETYPE_PEM, PemToDer manages the decryption */ - /* If private key type PKCS8 header wasn't already removed (algoId == 0) */ - if (ret >= 0 && format != WOLFSSL_FILETYPE_PEM && info->passwd_cb && - type == PRIVATEKEY_TYPE && algId == 0) - { - int passwordSz = NAME_SZ; - #ifndef WOLFSSL_SMALL_STACK - char password[NAME_SZ]; - #else - char* password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING); - if (password == NULL) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); - #endif - FreeDer(&der); - return MEMORY_E; - } - #endif - /* get password */ - ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ, - info->passwd_userdata); - if (ret >= 0) { - passwordSz = ret; - - /* PKCS8 decrypt */ - ret = ToTraditionalEnc(der->buffer, der->length, - password, passwordSz, &algId); - if (ret >= 0) { - der->length = ret; - } - ret = 0; /* ignore failures and try parsing directly unencrypted */ - - ForceZero(password, passwordSz); - } - + /* info is only used for private key with DER or PEM, so free now */ + if (ret < 0 || type != PRIVATEKEY_TYPE || format == WOLFSSL_FILETYPE_RAW) { #ifdef WOLFSSL_SMALL_STACK - XFREE(password, heap, DYNAMIC_TYPE_STRING); + XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); #endif } -#endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */ - -#ifdef WOLFSSL_SMALL_STACK - XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); -#endif /* check for error */ if (ret < 0) { @@ -5187,196 +5378,62 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, else if (algId == ED25519k) ed25519Key = 1; #endif - #ifndef NO_RSA - if (!eccKey && !ed25519Key) { - /* make sure RSA key can be used */ - #ifdef WOLFSSL_SMALL_STACK - RsaKey* key = NULL; + + ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites, + &rsaKey, &eccKey, &ed25519Key, heap, devId); + + #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED) + /* for WOLFSSL_FILETYPE_PEM, PemToDer manages the decryption */ + /* If private key type PKCS8 header wasn't already removed (algoId == 0) */ + if ((ret != 0 || (!rsaKey && !eccKey && !ed25519Key)) + && format != WOLFSSL_FILETYPE_PEM && info->passwd_cb && algId == 0) + { + int passwordSz = NAME_SZ; + #ifndef WOLFSSL_SMALL_STACK + char password[NAME_SZ]; #else - RsaKey key[1]; - #endif - - #ifdef WOLFSSL_SMALL_STACK - key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA); - if (key == NULL) + char* password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING); + if (password == NULL) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); + #endif + FreeDer(&der); return MEMORY_E; + } #endif + /* get password */ + ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ, + info->passwd_userdata); + if (ret >= 0) { + passwordSz = ret; - ret = wc_InitRsaKey_ex(key, heap, devId); - if (ret == 0) { - idx = 0; - if (wc_RsaPrivateKeyDecode(der->buffer, &idx, key, der->length) - != 0) { - #ifdef HAVE_ECC - /* could have DER ECC (or pkcs8 ecc), no easy way to tell */ - eccKey = 1; /* try it next */ - #elif defined(HAVE_ED25519) - ed25519Key = 1; /* try it next */ - #else - WOLFSSL_MSG("RSA decode failed and ECC not enabled to try"); - ret = WOLFSSL_BAD_FILE; - #endif + /* PKCS8 decrypt */ + ret = ToTraditionalEnc(der->buffer, der->length, + password, passwordSz, &algId); + if (ret >= 0) { + der->length = ret; } - else { - /* check that the size of the RSA key is enough */ - int minRsaSz = ssl ? ssl->options.minRsaKeySz : - ctx->minRsaKeySz; - keySz = wc_RsaEncryptSize((RsaKey*)key); - if (keySz < minRsaSz) { - ret = RSA_KEY_SIZE_E; - WOLFSSL_MSG("Private Key size too small"); - } + /* ignore failures and try parsing as unencrypted */ - if (ssl) { - ssl->buffers.keyType = rsa_sa_algo; - ssl->buffers.keySz = keySz; - } - else if(ctx) { - ctx->privateKeyType = rsa_sa_algo; - ctx->privateKeySz = keySz; - } - - rsaKey = 1; - (void)rsaKey; /* for no ecc builds */ - - if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { - ssl->options.haveStaticECC = 0; - resetSuites = 1; - } - } - - wc_FreeRsaKey(key); + ForceZero(password, passwordSz); } #ifdef WOLFSSL_SMALL_STACK - XFREE(key, heap, DYNAMIC_TYPE_RSA); + XFREE(password, heap, DYNAMIC_TYPE_STRING); #endif - - if (ret != 0) - return ret; + ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, + &resetSuites, &rsaKey, &eccKey, &ed25519Key, heap, devId); } + #endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */ + + #ifdef WOLFSSL_SMALL_STACK + XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO); #endif - #ifdef HAVE_ECC - if (!rsaKey && !ed25519Key) { - /* make sure ECC key can be used */ - #ifdef WOLFSSL_SMALL_STACK - ecc_key* key = NULL; - #else - ecc_key key[1]; - #endif - #ifdef WOLFSSL_SMALL_STACK - key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC); - if (key == NULL) - return MEMORY_E; - #endif - - if (wc_ecc_init_ex(key, heap, devId) == 0) { - idx = 0; - if (wc_EccPrivateKeyDecode(der->buffer, &idx, key, - der->length) == 0) { - /* check for minimum ECC key size and then free */ - int minKeySz = ssl ? ssl->options.minEccKeySz : - ctx->minEccKeySz; - keySz = wc_ecc_size(key); - if (keySz < minKeySz) { - WOLFSSL_MSG("ECC private key too small"); - ret = ECC_KEY_SIZE_E; - } - - eccKey = 1; - if (ssl) { - ssl->options.haveStaticECC = 1; - ssl->buffers.keyType = ecc_dsa_sa_algo; - ssl->buffers.keySz = keySz; - } - else if (ctx) { - ctx->haveStaticECC = 1; - ctx->privateKeyType = ecc_dsa_sa_algo; - ctx->privateKeySz = keySz; - } - - if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { - resetSuites = 1; - } - } - else - eccKey = 0; - - wc_ecc_free(key); - } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(key, heap, DYNAMIC_TYPE_ECC); - #endif - - if (ret != 0) - return ret; - } - #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 - if (!rsaKey && !eccKey) { - /* make sure Ed25519 key can be used */ - #ifdef WOLFSSL_SMALL_STACK - ed25519_key* key = NULL; - #else - ed25519_key key[1]; - #endif - - #ifdef WOLFSSL_SMALL_STACK - key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap, - DYNAMIC_TYPE_ED25519); - if (key == NULL) - return MEMORY_E; - #endif - - ret = wc_ed25519_init(key); - if (ret == 0) { - idx = 0; - if (wc_Ed25519PrivateKeyDecode(der->buffer, &idx, key, - der->length) != 0) { - ret = WOLFSSL_BAD_FILE; - } - - if (ret == 0) { - /* check for minimum key size and then free */ - int minKeySz = ssl ? ssl->options.minEccKeySz : - ctx->minEccKeySz; - keySz = ED25519_KEY_SIZE; - if (keySz < minKeySz) { - WOLFSSL_MSG("ED25519 private key too small"); - ret = ECC_KEY_SIZE_E; - } - } - if (ret == 0) { - if (ssl) { - ssl->buffers.keyType = ed25519_sa_algo; - ssl->buffers.keySz = keySz; - } - else if (ctx) { - ctx->privateKeyType = ed25519_sa_algo; - ctx->privateKeySz = keySz; - } - - ed25519Key = 1; - if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { - resetSuites = 1; - } - } - - wc_ed25519_free(key); - } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(key, heap, DYNAMIC_TYPE_ED25519); - #endif - if (ret != 0) - return ret; - } - #else + if (ret != 0) + return ret; if (!rsaKey && !eccKey && !ed25519Key) return WOLFSSL_BAD_FILE; - #endif (void)ed25519Key; (void)devId; } @@ -7604,22 +7661,21 @@ void wolfSSL_X509_EXTENSION_free(WOLFSSL_X509_EXTENSION* x) if (asn1.length > 0 && asn1.data != NULL && asn1.isDynamic) XFREE(asn1.data, NULL, DYNAMIC_TYPE_OPENSSL); - wolfSSL_sk_ASN1_OBJECT_free(x->ext_sk); + wolfSSL_sk_free(x->ext_sk); XFREE(x, NULL, DYNAMIC_TYPE_X509_EXT); } -/* Creates and returns a new WOLFSSL_CIPHER stack. */ +/* Creates and returns a new WOLFSSL_X509_EXTENSION stack. */ WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void) { - WOLFSSL_STACK* sk = NULL; + WOLFSSL_STACK* sk; WOLFSSL_ENTER("wolfSSL_sk_new_x509_ext"); sk = wolfSSL_sk_new_null(); - if (sk == NULL) - return NULL; - sk->type = STACK_TYPE_X509_EXT; - + if (sk) { + sk->type = STACK_TYPE_X509_EXT; + } return sk; } @@ -7693,6 +7749,32 @@ void wolfSSL_sk_X509_EXTENSION_free(WOLFSSL_STACK* sk) XFREE(sk, NULL, DYNAMIC_TYPE_X509); } +int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* str, int pos, + int val) +{ + int bytes_cnt = pos/8; + int bit = 1<<(7-(pos%8)); + char* temp; + + if (!str || (val != 0 && val != 1)) { + return WOLFSSL_FAILURE; + } + + if (bytes_cnt+1 > str->length) { + if (!(temp = (char*)XREALLOC(str->data, bytes_cnt+1, NULL, + DYNAMIC_TYPE_OPENSSL))) { + return WOLFSSL_FAILURE; + } + XMEMSET(temp+str->length, 0, bytes_cnt+1 - str->length); + str->data = temp; + str->length = bytes_cnt+1; + } + + str->data[bytes_cnt] &= ~bit; + str->data[bytes_cnt] |= val ? bit : 0; + return WOLFSSL_SUCCESS; +} + /* Gets the X509_EXTENSION* ext based on it's location in WOLFSSL_X509* x509. * * x509 : The X509 structure to look for the extension. @@ -7874,6 +7956,7 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) return NULL; } XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT))); + sk->type = STACK_TYPE_OBJ; /* Add CaIssuers object to stack */ if (x509->authInfoCaIssuer != NULL && @@ -8000,68 +8083,67 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) break; case ALT_NAMES_OID: - { - WOLFSSL_GENERAL_NAME* gn = NULL; - DNS_entry* dns = NULL; - if (!isSet) - break; + { + WOLFSSL_GENERAL_NAME* gn = NULL; + DNS_entry* dns = NULL; + if (!isSet) + break; - sk = (WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)*)XMALLOC( - sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)), NULL, - DYNAMIC_TYPE_ASN1); - if (sk == NULL) { - return NULL; - } - XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME))); - sk->type = STACK_TYPE_GEN_NAME; + sk = (WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)*)XMALLOC( + sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)), NULL, + DYNAMIC_TYPE_ASN1); + if (sk == NULL) { + return NULL; + } + XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME))); + sk->type = STACK_TYPE_GEN_NAME; - if (x509->subjAltNameSet && x509->altNames != NULL) { - /* alt names are DNS_entry structs */ - dns = x509->altNames; - /* Currenlty only support GEN_DNS type */ - while (dns != NULL) { - gn = wolfSSL_GENERAL_NAME_new(); - if (gn == NULL) { - WOLFSSL_MSG("Error creating GENERAL_NAME"); - wolfSSL_sk_free(sk); - return NULL; - } - - gn->type = dns->type; - gn->d.ia5->length = (int)XSTRLEN(dns->name); - if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name, - gn->d.ia5->length) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("ASN1_STRING_set failed"); - wolfSSL_GENERAL_NAME_free(gn); - wolfSSL_sk_free(sk); - return NULL; - } - - dns = dns->next; - /* last dns in list add at end of function */ - if (dns != NULL) { - if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != - WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error pushing onto stack"); - wolfSSL_GENERAL_NAME_free(gn); - wolfSSL_sk_free(sk); - sk = NULL; - } - } + if (x509->subjAltNameSet && x509->altNames != NULL) { + /* alt names are DNS_entry structs */ + dns = x509->altNames; + /* Currenlty only support GEN_DNS type */ + while (dns != NULL) { + gn = wolfSSL_GENERAL_NAME_new(); + if (gn == NULL) { + WOLFSSL_MSG("Error creating GENERAL_NAME"); + wolfSSL_sk_free(sk); + return NULL; } - if (wolfSSL_sk_GENERAL_NAME_push(sk,gn) != - WOLFSSL_SUCCESS) { + + gn->type = dns->type; + gn->d.ia5->length = (int)XSTRLEN(dns->name); + if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name, + gn->d.ia5->length) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("ASN1_STRING_set failed"); + wolfSSL_GENERAL_NAME_free(gn); + wolfSSL_sk_free(sk); + return NULL; + } + + dns = dns->next; + /* last dns in list add at end of function */ + if (dns != NULL) { + if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != + WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error pushing onto stack"); wolfSSL_GENERAL_NAME_free(gn); wolfSSL_sk_free(sk); sk = NULL; + } } } - ext->ext_sk = sk; - ext->crit = x509->subjAltNameCrit; - + if (wolfSSL_sk_GENERAL_NAME_push(sk,gn) != + WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing onto stack"); + wolfSSL_GENERAL_NAME_free(gn); + wolfSSL_sk_free(sk); + sk = NULL; + } } + ext->ext_sk = sk; + ext->crit = x509->subjAltNameCrit; break; + } default: WOLFSSL_MSG("Unknown extension type found, parsing OID"); @@ -8133,6 +8215,7 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) return NULL; } ext->value.data = (char*)XMALLOC(length, NULL, DYNAMIC_TYPE_ASN1); + ext->value.isDynamic = 1; if (ext->value.data == NULL) { WOLFSSL_MSG("Failed to malloc ASN1_STRING data"); wolfSSL_X509_EXTENSION_free(ext); @@ -8191,24 +8274,25 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, /* Print extension based on the type */ nid = wolfSSL_OBJ_obj2nid(obj); - switch(nid) { + switch (nid) { case BASIC_CA_OID: - { - char isCa[] = "TRUE"; - char notCa[] = "FALSE"; - XSNPRINTF(tmp, sz, "%*sCA:%s", indent, "", - obj->ca ? isCa : notCa); - break; - } + { + char isCa[] = "TRUE"; + char notCa[] = "FALSE"; + XSNPRINTF(tmp, sz, "%*sCA:%s", indent, "", + obj->ca ? isCa : notCa); + break; + } case ALT_NAMES_OID: - { - WOLFSSL_STACK* sk; - char* val; - int len; - tmp[0] = '\0'; /* Make sure tmp is null-terminated */ + { + WOLFSSL_STACK* sk; + char* val; + int len; + tmp[0] = '\0'; /* Make sure tmp is null-terminated */ - sk = ext->ext_sk; - while (sk != NULL) { + sk = ext->ext_sk; + while (sk != NULL) { + if (sk->type == STACK_TYPE_GEN_NAME && sk->data.gn) { /* str is GENERAL_NAME for subject alternative name ext */ str = sk->data.gn->d.ia5; len = str->length + 2; /* + 2 for NULL char and "," */ @@ -8230,21 +8314,20 @@ int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, XSTRNCAT(tmp, val, len); XFREE(val, NULL, DYNAMIC_TYPE_TMP_BUFFER); - sk = sk->next; } - break; + sk = sk->next; } - + break; + } case AUTH_KEY_OID: case SUBJ_KEY_OID: - { - char* asn1str; - asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str); - XSNPRINTF(tmp, sz, "%*s%s", indent, "", asn1str); - XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER); - break; - } - + { + char* asn1str; + asn1str = wolfSSL_i2s_ASN1_STRING(NULL, str); + XSNPRINTF(tmp, sz, "%*s%s", indent, "", asn1str); + XFREE(asn1str, NULL, DYNAMIC_TYPE_TMP_BUFFER); + break; + } case AUTH_INFO_OID: case CERT_POLICY_OID: case CRL_DIST_OID: @@ -8359,9 +8442,8 @@ const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex) void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext) { const WOLFSSL_v3_ext_method* method; - int ret, i; + int ret; WOLFSSL_ASN1_OBJECT* object; - WOLFSSL_ASN1_OBJECT* aiaEntry; WOLFSSL_BASIC_CONSTRAINTS* bc; WOLFSSL_AUTHORITY_KEYID* akey; WOLFSSL_ASN1_STRING* asn1String, *newString; @@ -8522,8 +8604,6 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext) /* authorityInfoAccess */ case (NID_info_access): WOLFSSL_MSG("AuthorityInfoAccess"); - /* i indexes into stack,sk,using wolfSSL_sk_value(sk,i) */ - i = 0; sk = ext->ext_sk; if (sk == NULL) { @@ -8539,12 +8619,21 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext) } aia->type = STACK_TYPE_ACCESS_DESCRIPTION; - aiaEntry = (WOLFSSL_ASN1_OBJECT*)wolfSSL_sk_value(sk,i); - /* ACCESS_DESCRIPTION has two members, method and location. + while (sk) { + WOLFSSL_ACCESS_DESCRIPTION* ad; + WOLFSSL_ASN1_OBJECT* aiaEntry; + + if (sk->type != STACK_TYPE_OBJ) { + sk = sk->next; + continue; + } + + aiaEntry = sk->data.obj; + + /* ACCESS_DESCRIPTION has two members, method and location. Method: ASN1_OBJECT as either AIA_OCSP_OID or AIA_CA_ISSUER_OID Location: GENERAL_NAME structure containing the URI. */ - while (aiaEntry != NULL) { - WOLFSSL_ACCESS_DESCRIPTION* ad; + ad = (WOLFSSL_ACCESS_DESCRIPTION*) XMALLOC(sizeof(WOLFSSL_ACCESS_DESCRIPTION), NULL, DYNAMIC_TYPE_X509_EXT); @@ -8593,15 +8682,15 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext) /* Push to AUTHORITY_INFO_ACCESS stack */ ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad); if (ret != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error pushing ASN1 object onto stack"); + WOLFSSL_MSG("Error pushing ASN1 AD onto stack"); wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL); wolfSSL_ASN1_OBJECT_free(ad->method); XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT); XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT); return NULL; } - i++; - aiaEntry = (WOLFSSL_ASN1_OBJECT*)wolfSSL_sk_value(sk,i); + + sk = sk->next; } return aia; @@ -8724,6 +8813,38 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos) #endif /* OPENSSL_ALL */ +WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void) +{ + WOLFSSL_ASN1_BIT_STRING* str; + + str = (WOLFSSL_ASN1_BIT_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_BIT_STRING), + NULL, DYNAMIC_TYPE_OPENSSL); + if (str) { + XMEMSET(str, 0, sizeof(WOLFSSL_ASN1_BIT_STRING)); + } + return str; +} + +void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING* str) +{ + if (str) { + if (str->data) { + XFREE(str->data, NULL, DYNAMIC_TYPE_OPENSSL); + str->data = NULL; + } + XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +int wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING* str, int i) +{ + if (!str || !str->data || str->length <= (i/8) || i < 0) { + return WOLFSSL_FAILURE; + } + + return str->data[i/8] & (1<<(7-(i%8))) ? 1 : 0; +} + /* Looks for the extension matching the passed in nid * * c : if not null then is set to status value -2 if multiple occurrences @@ -8732,15 +8853,18 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos) * nid : Extension OID to be found. * idx : if NULL return first extension found match, otherwise start search at * idx location and set idx to the location of extension returned. - * returns NULL or a pointer to an WOLFSSL_STACK holding extension structure + * returns NULL or a pointer to an WOLFSSL_ASN1_BIT_STRING (for KEY_USAGE_OID) + * or WOLFSSL_STACK (for other) + * holding extension structure * * NOTE code for decoding extensions is in asn.c DecodeCertExtensions -- * use already decoded extension in this function to avoid decoding twice. * Currently we do not make use of idx since getting pre decoded extensions. */ -void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, - int nid, int* c, int* idx) +void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, + int* idx) { + void* ret = NULL; WOLFSSL_STACK* sk = NULL; WOLFSSL_ASN1_OBJECT* obj = NULL; WOLFSSL_GENERAL_NAME* gn = NULL; @@ -8755,18 +8879,12 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, *c = -1; /* default to not found */ } - sk = wolfSSL_sk_new_asn1_obj(); - if (sk == NULL) { - return NULL; - } - switch (nid) { case BASIC_CA_OID: if (x509->basicConstSet) { obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - wolfSSL_sk_ASN1_OBJECT_free(sk); return NULL; } if (c != NULL) { @@ -8776,83 +8894,79 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, obj->grp = oidCertExtType; obj->nid = nid; obj->dynamic |= WOLFSSL_ASN1_DYNAMIC; - #if defined(WOLFSSL_APACHE_HTTPD) - obj->ca = x509->basicConstSet; + #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \ + defined(WOLFSSL_APACHE_HTTPD) + obj->ca = x509->isCa; #endif } else { WOLFSSL_MSG("No Basic Constraint set"); } - - /* Stack wasn't used, so free before returning obj */ - wolfSSL_sk_ASN1_OBJECT_free(sk); - sk = NULL; - return obj; case ALT_NAMES_OID: - { - DNS_entry* dns = NULL; - /* Free ASN1_OBJECT stack and malloc GENERAL_NAME stack */ - wolfSSL_sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)*)XMALLOC( - sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)), NULL, - DYNAMIC_TYPE_ASN1); - if (sk == NULL) { - return NULL; - } - XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME))); - sk->type = STACK_TYPE_GEN_NAME; + { + DNS_entry* dns = NULL; + /* Malloc GENERAL_NAME stack */ + sk = (WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)*)XMALLOC( + sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)), NULL, + DYNAMIC_TYPE_ASN1); + if (sk == NULL) { + return NULL; + } + XMEMSET(sk, 0, sizeof(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME))); + sk->type = STACK_TYPE_GEN_NAME; - if (x509->subjAltNameSet && x509->altNames != NULL) { - /* alt names are DNS_entry structs */ - if (c != NULL) { - if (x509->altNames->next != NULL) { - *c = -2; /* more then one found */ - } - else { - *c = x509->subjAltNameCrit; - } + if (x509->subjAltNameSet && x509->altNames != NULL) { + /* alt names are DNS_entry structs */ + if (c != NULL) { + if (x509->altNames->next != NULL) { + *c = -2; /* more then one found */ + } + else { + *c = x509->subjAltNameCrit; + } + } + + dns = x509->altNames; + /* Currently only support GEN_DNS type */ + while (dns != NULL) { + gn = wolfSSL_GENERAL_NAME_new(); + if (gn == NULL) { + WOLFSSL_MSG("Error creating GENERAL_NAME"); + wolfSSL_sk_free(sk); + return NULL; } - dns = x509->altNames; - /* Currenlty only support GEN_DNS type */ - while (dns != NULL) { - gn = wolfSSL_GENERAL_NAME_new(); - if (gn == NULL) { - WOLFSSL_MSG("Error creating GENERAL_NAME"); - wolfSSL_sk_free(sk); - return NULL; - } + gn->type = dns->type; + gn->d.ia5->length = (int)XSTRLEN(dns->name); + if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name, + gn->d.ia5->length) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("ASN1_STRING_set failed"); + wolfSSL_GENERAL_NAME_free(gn); + wolfSSL_sk_free(sk); + return NULL; + } - gn->type = dns->type; - gn->d.ia5->length = (int)XSTRLEN(dns->name); - if (wolfSSL_ASN1_STRING_set(gn->d.ia5, dns->name, - gn->d.ia5->length) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("ASN1_STRING_set failed"); - wolfSSL_GENERAL_NAME_free(gn); - wolfSSL_sk_free(sk); - return NULL; - } - - dns = dns->next; - /* last dns in list add at end of function */ - if (dns != NULL) { - if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != - WOLFSSL_SUCCESS) { + dns = dns->next; + /* last dns in list add at end of function */ + if (dns != NULL) { + if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != + WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error pushing ASN1 object onto stack"); wolfSSL_GENERAL_NAME_free(gn); wolfSSL_sk_free(sk); sk = NULL; - } } } } - else { - WOLFSSL_MSG("No Alt Names set"); - } } + else { + WOLFSSL_MSG("No Alt Names set"); + } + break; + } case CRL_DIST_OID: if (x509->CRLdistSet && x509->CRLInfo != NULL) { @@ -8862,7 +8976,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - wolfSSL_sk_ASN1_OBJECT_free(sk); return NULL; } obj->type = CRL_DIST_OID; @@ -8885,7 +8998,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - wolfSSL_sk_ASN1_OBJECT_free(sk); return NULL; } obj->type = AUTH_INFO_OID; @@ -8908,7 +9020,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - wolfSSL_sk_ASN1_OBJECT_free(sk); return NULL; } obj->type = AUTH_KEY_OID; @@ -8931,7 +9042,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - wolfSSL_sk_ASN1_OBJECT_free(sk); return NULL; } obj->type = SUBJ_KEY_OID; @@ -8947,41 +9057,26 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, break; case CERT_POLICY_OID: - #ifdef WOLFSSL_CERT_EXT - { - int i; + { + #ifdef WOLFSSL_CERT_EXT + int i; - if (x509->certPoliciesNb > 0) { - if (c != NULL) { - if (x509->certPoliciesNb > 1) { - *c = -2; - } - else { - *c = 0; - } + if (x509->certPoliciesNb > 0) { + if (c != NULL) { + if (x509->certPoliciesNb > 1) { + *c = -2; } + else { + *c = 0; + } + } - for (i = 0; i < x509->certPoliciesNb - 1; i++) { - obj = wolfSSL_ASN1_OBJECT_new(); - if (obj == NULL) { - WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - wolfSSL_sk_ASN1_OBJECT_free(sk); - return NULL; - } - obj->type = CERT_POLICY_OID; - obj->grp = oidCertExtType; - obj->obj = (byte*)(x509->certPolicies[i]); - obj->objSz = MAX_CERTPOL_SZ; - obj->dynamic |= WOLFSSL_ASN1_DYNAMIC; - obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA; - if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) - != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error pushing ASN1 object onto stack"); - wolfSSL_ASN1_OBJECT_free(obj); - wolfSSL_sk_ASN1_OBJECT_free(sk); - sk = NULL; - } - } + sk = wolfSSL_sk_new_asn1_obj(); + if (sk == NULL) { + return NULL; + } + + for (i = 0; i < x509->certPoliciesNb - 1; i++) { obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); @@ -8994,40 +9089,13 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, obj->objSz = MAX_CERTPOL_SZ; obj->dynamic |= WOLFSSL_ASN1_DYNAMIC; obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA; - } - else { - WOLFSSL_MSG("No Cert Policy set"); - } - } - #else - #ifdef WOLFSSL_SEP - if (x509->certPolicySet) { - if (c != NULL) { - *c = x509->certPolicyCrit; - } - obj = wolfSSL_ASN1_OBJECT_new(); - if (obj == NULL) { - WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing ASN1 object onto stack"); + wolfSSL_ASN1_OBJECT_free(obj); wolfSSL_sk_ASN1_OBJECT_free(sk); - return NULL; + sk = NULL; } - obj->type = CERT_POLICY_OID; - obj->grp = oidCertExtType; - obj->dynamic |= WOLFSSL_ASN1_DYNAMIC; - } - else { - WOLFSSL_MSG("No Cert Policy set"); - } - #else - WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT"); - #endif /* WOLFSSL_SEP */ - #endif /* WOLFSSL_CERT_EXT */ - break; - - case KEY_USAGE_OID: - if (x509->keyUsageSet) { - if (c != NULL) { - *c = x509->keyUsageCrit; } obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { @@ -9035,18 +9103,68 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, wolfSSL_sk_ASN1_OBJECT_free(sk); return NULL; } - obj->type = KEY_USAGE_OID; + obj->type = CERT_POLICY_OID; obj->grp = oidCertExtType; - obj->obj = (byte*)&(x509->keyUsage); - obj->objSz = sizeof(word16); + obj->obj = (byte*)(x509->certPolicies[i]); + obj->objSz = MAX_CERTPOL_SZ; obj->dynamic |= WOLFSSL_ASN1_DYNAMIC; obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA; } + else { + WOLFSSL_MSG("No Cert Policy set"); + } + #elif defined(WOLFSSL_SEP) + if (x509->certPolicySet) { + if (c != NULL) { + *c = x509->certPolicyCrit; + } + obj = wolfSSL_ASN1_OBJECT_new(); + if (obj == NULL) { + WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); + return NULL; + } + obj->type = CERT_POLICY_OID; + obj->grp = oidCertExtType; + obj->dynamic |= WOLFSSL_ASN1_DYNAMIC; + } + else { + WOLFSSL_MSG("No Cert Policy set"); + } + #else + WOLFSSL_MSG("wolfSSL not built with WOLFSSL_SEP or WOLFSSL_CERT_EXT"); + #endif + break; + } + case KEY_USAGE_OID: + { + WOLFSSL_ASN1_BIT_STRING* bit_str = NULL; + if (x509->keyUsageSet) { + if (c != NULL) { + *c = x509->keyUsageCrit; + } + + bit_str = wolfSSL_ASN1_BIT_STRING_new(); + if (bit_str == NULL) { + WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_BIT_STRING struct"); + return NULL; + } + + bit_str->type = KEY_USAGE_OID; + bit_str->flags = 0; + bit_str->length = sizeof(word16); + bit_str->data = (char*)XMALLOC(bit_str->length, NULL, DYNAMIC_TYPE_OPENSSL); + if (bit_str->data == NULL) { + wolfSSL_ASN1_BIT_STRING_free(bit_str); + return NULL; + } + XMEMCPY(bit_str->data, &x509->keyUsage, bit_str->length); + } else { WOLFSSL_MSG("No Key Usage set"); } - break; - + /* don't add stack of and return bit string directly */ + return bit_str; + } case INHIBIT_ANY_OID: WOLFSSL_MSG("INHIBIT ANY extension not supported"); break; @@ -9064,7 +9182,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, obj = wolfSSL_ASN1_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - wolfSSL_sk_ASN1_OBJECT_free(sk); return NULL; } obj->type = EXT_KEY_USAGE_OID; @@ -9111,30 +9228,42 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, WOLFSSL_MSG("Unsupported/Unknown extension OID"); } - if (obj != NULL) { - if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error pushing ASN1 object onto stack"); - wolfSSL_ASN1_OBJECT_free(obj); - wolfSSL_sk_ASN1_OBJECT_free(sk); - sk = NULL; + /* make sure stack of is allocated */ + if ((obj || gn) && sk == NULL) { + sk = wolfSSL_sk_new_asn1_obj(); + if (sk == NULL) { + goto err; } } - else if (gn != NULL) { - if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Error pushing GENERAL_NAME object onto stack"); - wolfSSL_GENERAL_NAME_free(gn); - wolfSSL_sk_free(sk); - sk = NULL; - } + if (obj && wolfSSL_sk_ASN1_OBJECT_push(sk, obj) == WOLFSSL_SUCCESS) { + /* obj pushed successfully on stack */ } - else { /* no ASN1 object found for extension, free stack */ - wolfSSL_sk_ASN1_OBJECT_free(sk); - sk = NULL; + else if (gn && wolfSSL_sk_GENERAL_NAME_push(sk, gn) == WOLFSSL_SUCCESS) { + /* gn pushed successfully on stack */ } + else { + /* Nothing to push or push failed */ + WOLFSSL_MSG("Error pushing ASN1_OBJECT or GENERAL_NAME object onto stack " + "or nothing to push."); + goto err; + } + ret = sk; (void)idx; - return sk; + return ret; + +err: + if (obj) { + wolfSSL_ASN1_OBJECT_free(obj); + } + if (gn) { + wolfSSL_GENERAL_NAME_free(gn); + } + if (sk) { + wolfSSL_sk_ASN1_OBJECT_free(sk); + } + return NULL; } #ifndef NO_WOLFSSL_STUB @@ -9193,7 +9322,7 @@ WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(WOLFSSL_X509_EXTENSION* ext } /* this function makes the assumption that out buffer is big enough for digest*/ -int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out, +int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out, unsigned int* outSz, const WOLFSSL_EVP_MD* evp, WOLFSSL_ENGINE* eng) { @@ -13673,10 +13802,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || HAVE_WEBSERVER */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) - WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_SSL_CTX_get_client_CA_list( + WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list( const WOLFSSL_CTX *s) { - WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_client_CA_list"); + WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list"); if (s == NULL) return NULL; @@ -13712,13 +13841,18 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (subjectName == NULL) break; - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_OPENSSL); + node = wolfSSL_sk_new_node(NULL); if (node == NULL) break; + node->type = STACK_TYPE_X509_NAME; /* Need a persistent copy of the subject name. */ node->data.name = wolfSSL_X509_NAME_dup(subjectName); + /* + * Original cert will be freed so make sure not to try to access + * it in the future. + */ + node->data.name->x509 = NULL; /* Put node on the front of the list. */ node->num = (list == NULL) ? 1 : list->num + 1; @@ -15815,15 +15949,24 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #ifndef NO_AES static int AesSetKey_ex(Aes* aes, const byte* key, word32 len, - const byte* iv, int dir) + const byte* iv, int dir, int direct) { int ret; /* wc_AesSetKey clear aes.reg if iv == NULL. Keep IV for openSSL compatibility */ - if(iv == NULL) + if (iv == NULL) XMEMCPY((byte *)aes->tmp, (byte *)aes->reg, AES_BLOCK_SIZE); - ret = wc_AesSetKey(aes, key, len, iv, dir); - if(iv == NULL) + if (direct) { + #if defined(WOLFSSL_AES_DIRECT) + ret = wc_AesSetKeyDirect(aes, key, len, iv, dir); + #else + ret = NOT_COMPILED_IN; + #endif + } + else { + ret = wc_AesSetKey(aes, key, len, iv, dir); + } + if (iv == NULL) XMEMCPY((byte *)aes->reg, (byte *)aes->tmp, AES_BLOCK_SIZE); return ret; } @@ -15852,10 +15995,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if (ctx->cipherType == WOLFSSL_EVP_CIPH_TYPE_INIT){ /* only first EVP_CipherInit invoke. ctx->cipherType is set below */ XMEMSET(&ctx->cipher, 0, sizeof(ctx->cipher)); - ctx->bufUsed = 0; - ctx->lastUsed = 0; ctx->flags = 0; } + /* always clear buffer state */ + ctx->bufUsed = 0; + ctx->lastUsed = 0; #ifndef NO_AES #ifdef HAVE_AES_CBC @@ -15872,7 +16016,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0); if (ret != 0) return ret; } @@ -15896,7 +16040,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0); if (ret != 0) return ret; } @@ -15920,7 +16064,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 0); if (ret != 0){ WOLFSSL_MSG("AesSetKey() failed"); return ret; @@ -16041,12 +16185,15 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->cipherType = AES_128_CTR_TYPE; ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 16; - ctx->block_size = AES_BLOCK_SIZE; + ctx->block_size = NO_PADDING_BLOCK_SIZE; +#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) + ctx->cipher.aes.left = 0; +#endif if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); + AES_ENCRYPTION, 1); if (ret != 0) return ret; } @@ -16065,12 +16212,15 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 24; - ctx->block_size = AES_BLOCK_SIZE; + ctx->block_size = NO_PADDING_BLOCK_SIZE; +#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) + ctx->cipher.aes.left = 0; +#endif if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); + AES_ENCRYPTION, 1); if (ret != 0) return ret; } @@ -16089,12 +16239,15 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 32; - ctx->block_size = AES_BLOCK_SIZE; + ctx->block_size = NO_PADDING_BLOCK_SIZE; +#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) + ctx->cipher.aes.left = 0; +#endif if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); + AES_ENCRYPTION, 1); if (ret != 0) return ret; } @@ -16119,7 +16272,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1); } if (ret != 0) return ret; @@ -16138,7 +16291,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1); } if (ret != 0) return ret; @@ -16157,7 +16310,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = enc ? 1 : 0; if (key) { ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, NULL, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, 1); } if (ret != 0) return ret; @@ -18101,25 +18254,25 @@ byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in, /* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */ #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) -WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(WOLFSSL_X509* x509) +WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509) { WOLFSSL_ENTER("wolfSSL_X509_get_notBefore"); if (x509 == NULL) return NULL; - return &x509->notBefore; + return (WOLFSSL_ASN1_TIME*)&x509->notBefore; } -WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(WOLFSSL_X509* x509) +WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509) { WOLFSSL_ENTER("wolfSSL_X509_get_notAfter"); if (x509 == NULL) return NULL; - return &x509->notAfter; + return (WOLFSSL_ASN1_TIME*)&x509->notAfter; } @@ -18151,6 +18304,7 @@ int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x50 /* push new x509 onto head of stack */ node->data.x509 = sk->data.x509; node->next = sk->next; + node->type = sk->type; sk->next = node; sk->data.x509 = x509; sk->num += 1; @@ -18194,7 +18348,7 @@ WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) { * returns a pointer to a WOLFSSL_X509 structure on success and NULL on * fail */ -void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i) +WOLFSSL_X509* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i) { WOLFSSL_ENTER("wolfSSL_sk_X509_value"); @@ -18206,11 +18360,20 @@ void* wolfSSL_sk_X509_value(STACK_OF(WOLFSSL_X509)* sk, int i) return sk->data.x509; } -void* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk) +WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk) { return wolfSSL_sk_X509_pop(sk); } +#ifndef NO_WOLFSSL_STUB +void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int x) +{ + (void) sk; + (void) x; + return NULL; +} +#endif + /* Free's all nodes in X509 stack. This is different then wolfSSL_sk_X509_free * in that it allows for choosing the function to use when freeing an X509s. @@ -18218,7 +18381,9 @@ void* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk) * sk stack to free nodes in * f X509 free function */ -void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*)){ +void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, + void (*f) (WOLFSSL_X509*)) +{ WOLFSSL_STACK* node; WOLFSSL_ENTER("wolfSSL_sk_X509_pop_free"); @@ -18229,38 +18394,14 @@ void wolfSSL_sk_X509_pop_free(STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*) /* parse through stack freeing each node */ node = sk->next; - while (sk->num > 1) { + while (node && sk->num > 1) { WOLFSSL_STACK* tmp = node; node = node->next; - f(tmp->data.x509); - XFREE(tmp, NULL, DYNAMIC_TYPE_X509); - sk->num -= 1; - } - - /* free head of stack */ - if (sk->num == 1) { - f(sk->data.x509); - } - XFREE(sk, NULL, DYNAMIC_TYPE_X509); -} - - -/* free structure for x509 stack */ -void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk) { - WOLFSSL_STACK* node; - - if (sk == NULL) { - return; - } - - /* parse through stack freeing each node */ - node = sk->next; - while (sk->num > 1) { - WOLFSSL_STACK* tmp = node; - node = node->next; - - wolfSSL_X509_free(tmp->data.x509); + if (f) + f(tmp->data.x509); + else + wolfSSL_X509_free(tmp->data.x509); tmp->data.x509 = NULL; XFREE(tmp, NULL, DYNAMIC_TYPE_X509); sk->num -= 1; @@ -18268,13 +18409,22 @@ void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk) { /* free head of stack */ if (sk->num == 1) { - wolfSSL_X509_free(sk->data.x509); + if (f) + f(sk->data.x509); + else + wolfSSL_X509_free(sk->data.x509); sk->data.x509 = NULL; } XFREE(sk, NULL, DYNAMIC_TYPE_X509); } +/* free structure for x509 stack */ +void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509)* sk) +{ + wolfSSL_sk_X509_pop_free(sk, NULL); +} + #endif /* NO_CERTS && OPENSSL_EXTRA */ #if defined(OPENSSL_ALL) || defined (WOLFSSL_QT) @@ -18323,45 +18473,59 @@ int wolfSSL_sk_ACCESS_DESCRIPTION_push(WOLF_STACK_OF(ACCESS_DESCRIPTION)* sk, * f free function to use, not called with wolfSSL */ void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk, - void f (WOLFSSL_ACCESS_DESCRIPTION*)) + void (*f) (WOLFSSL_ACCESS_DESCRIPTION*)) { WOLFSSL_STACK* node; WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free"); - (void)f; if (sk == NULL) { return; } /* parse through stack freeing each node */ node = sk->next; - while (sk->num > 1) { + while (node && sk->num > 1) { WOLFSSL_STACK* tmp = node; node = node->next; - if(tmp->data.access->method) { - wolfSSL_ASN1_OBJECT_free(tmp->data.access->method); - } - if(tmp->data.access->location) { - wolfSSL_GENERAL_NAME_free(tmp->data.access->location); + if (f) + f(tmp->data.access); + else { + if(tmp->data.access->method) { + wolfSSL_ASN1_OBJECT_free(tmp->data.access->method); + } + if(tmp->data.access->location) { + wolfSSL_GENERAL_NAME_free(tmp->data.access->location); + } } + tmp->data.access = NULL; XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); sk->num -= 1; } /* free head of stack */ if (sk->num == 1) { - if(sk->data.access->method) { - wolfSSL_ASN1_OBJECT_free(sk->data.access->method); - } - if(sk->data.access->location) { - wolfSSL_GENERAL_NAME_free(sk->data.access->location); - } + if (f) + f(sk->data.access); + else { + if(sk->data.access->method) { + + wolfSSL_ASN1_OBJECT_free(sk->data.access->method); + } + if(sk->data.access->location) { + wolfSSL_GENERAL_NAME_free(sk->data.access->location); + } + } + sk->data.access = NULL; } XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); } +void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk) +{ + wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, NULL); +} #endif #ifdef OPENSSL_EXTRA @@ -18380,7 +18544,6 @@ WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap) return sk; } - /* free's node but does not free internal data such as in->data.x509 */ void wolfSSL_sk_free_node(WOLFSSL_STACK* in) { @@ -18389,7 +18552,6 @@ void wolfSSL_sk_free_node(WOLFSSL_STACK* in) } } - /* pushes node "in" onto "stack" and returns pointer to the new stack on success * also handles internal "num" for number of nodes on stack * return WOLFSSL_SUCCESS on success @@ -18412,8 +18574,10 @@ int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in) return WOLFSSL_SUCCESS; } + /* Creates and returns new GENERAL_NAME structure */ -WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void) { +WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void) +{ WOLFSSL_GENERAL_NAME* gn; WOLFSSL_ENTER("GENERAL_NAME_new"); @@ -18462,45 +18626,36 @@ int wolfSSL_sk_GENERAL_NAME_push(WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)* sk, /* push new obj onto head of stack */ node->data.gn = sk->data.gn; - node->next = sk->next; - sk->next = node; - sk->data.gn = gn; - sk->num += 1; + node->next = sk->next; + sk->next = node; + sk->data.gn = gn; + sk->num += 1; return WOLFSSL_SUCCESS; } /* Returns the general name at index i from the stack * - * sk stack to get general name from - * i index to get + * sk stack to get general name from + * idx index to get * * return a pointer to the internal node of the stack */ -WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int i) +WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx) { - WOLFSSL_STACK* cur; - int j; + WOLFSSL_STACK* ret; - WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_value"); - - if (i < 0 || sk == NULL) { + if (sk == NULL) { return NULL; } - cur = sk; - for (j = 0; j < i && cur != NULL; j++) { - cur = cur->next; + ret = wolfSSL_sk_get_node(sk, idx); + if (ret != NULL) { + return ret->data.gn; } - - if (cur == NULL) { - return NULL; - } - - return cur->data.gn; + return NULL; } - /* Gets the number of nodes in the stack * * sk stack to get the number of nodes from @@ -18524,35 +18679,43 @@ int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk) * f free function to use, not called with wolfSSL */ void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk, - void f (WOLFSSL_GENERAL_NAME*)) + void (*f) (WOLFSSL_GENERAL_NAME*)) { WOLFSSL_STACK* node; WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_pop_free"); - (void)f; if (sk == NULL) { return; } /* parse through stack freeing each node */ node = sk->next; - while (sk->num > 1) { + while (node && sk->num > 1) { WOLFSSL_STACK* tmp = node; node = node->next; - wolfSSL_GENERAL_NAME_free(tmp->data.gn); + if (f) + f(tmp->data.gn); + else + wolfSSL_GENERAL_NAME_free(tmp->data.gn); XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); sk->num -= 1; } /* free head of stack */ if (sk->num == 1) { - wolfSSL_GENERAL_NAME_free(sk->data.gn); + if (f) + f(sk->data.gn); + else + wolfSSL_GENERAL_NAME_free(sk->data.gn); } XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); +} - +void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk) +{ + wolfSSL_sk_GENERAL_NAME_pop_free(sk, NULL); } @@ -18578,14 +18741,14 @@ void wolfSSL_AUTHORITY_INFO_ACCESS_free( #endif /* returns the node at index "idx", NULL if not found */ -static WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx) +WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx) { int i; WOLFSSL_STACK* ret = NULL; WOLFSSL_STACK* current = NULL; current = sk; - for (i = 0; i < idx && current != NULL; i++) { + for (i = 0; i <= idx && current != NULL; i++) { if (i == idx) { ret = current; break; @@ -18595,7 +18758,6 @@ static WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx) return ret; } - /* returns NULL on fail and pointer to internal data on success */ WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value( WOLFSSL_STACK* sk, int idx) @@ -18674,7 +18836,12 @@ void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES *gens) #if defined(OPENSSL_ALL) WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* wolfSSL_sk_X509_EXTENSION_new_null(void) { - return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)wolfSSL_sk_new_node(NULL); + WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); + if (sk) { + sk->type = STACK_TYPE_X509_EXT; + } + + return (WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)*)sk;; } /* returns the number of nodes on the stack */ @@ -18707,7 +18874,7 @@ WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value( /* frees all of the nodes and the values in stack */ void wolfSSL_sk_X509_EXTENSION_pop_free( WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, - void f (WOLFSSL_X509_EXTENSION*)) + void (*f) (WOLFSSL_X509_EXTENSION*)) { WOLFSSL_STACK* current; @@ -18720,7 +18887,8 @@ void wolfSSL_sk_X509_EXTENSION_pop_free( WOLFSSL_STACK* toFree = current; current = current->next; - f(toFree->data.ext); + if (f) + f(toFree->data.ext); wolfSSL_sk_free_node(toFree); } } @@ -19049,10 +19217,10 @@ int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop( - WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) + WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) { WOLFSSL_STACK* node; - WOLFSSL_ASN1_OBJECT* obj; + WOLFSSL_ASN1_OBJECT* obj; if (sk == NULL) { return NULL; @@ -19084,30 +19252,7 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop( */ void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) { - WOLFSSL_STACK* node; - - WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_free"); - - if (sk == NULL) { - return; - } - - /* parse through stack freeing each node */ - node = sk->next; - while ((node != NULL) && (sk->num > 1)) { - WOLFSSL_STACK* tmp = node; - node = node->next; - - wolfSSL_ASN1_OBJECT_free(tmp->data.obj); - XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); - sk->num -= 1; - } - - /* free head of stack */ - if (sk->num == 1) { - wolfSSL_ASN1_OBJECT_free(sk->data.obj); - } - XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); + wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL); } /* Free's all nodes in ASN1_OBJECT stack. @@ -19118,33 +19263,39 @@ void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) * f X509 free function */ void wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, - void (*func)(WOLFSSL_ASN1_OBJECT*)) + void (*f) (WOLFSSL_ASN1_OBJECT*)) { WOLFSSL_STACK* node; WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_pop_free"); - (void)func; - if ((sk == NULL) || (func == NULL)) { + if (sk == NULL) { WOLFSSL_MSG("Parameter error"); return; } /* parse through stack freeing each node */ node = sk->next; - while ((node != NULL) && (sk->num > 1)) { + while (node && sk->num > 1) { WOLFSSL_STACK* tmp = node; node = node->next; - func(tmp->data.obj); - + if (f) + f(tmp->data.obj); + else + wolfSSL_ASN1_OBJECT_free(tmp->data.obj); + tmp->data.obj = NULL; XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); sk->num -= 1; } /* free head of stack */ if (sk->num == 1) { - func(sk->data.obj); + if (f) + f(sk->data.obj); + else + wolfSSL_ASN1_OBJECT_free(sk->data.obj); + sk->data.obj = NULL; } XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); } @@ -19157,14 +19308,27 @@ int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in) The length of out is returned or a negative error code. The buffer *out should be free using OPENSSL_free(). */ - (void)out; - (void)in; - WOLFSSL_STUB("ASN1_STRING_to_UTF8"); - return -1; + unsigned char* buf; + int inLen; + + if (!out || !in) { + return -1; + } + + inLen = wolfSSL_ASN1_STRING_length(in); + buf = (unsigned char*)XMALLOC(inLen + 1, NULL, + DYNAMIC_TYPE_OPENSSL); + if (!buf) { + return -1; + } + XMEMCPY(buf, wolfSSL_ASN1_STRING_data(in), inLen + 1); + *out = buf; + return inLen; } /* Returns string representation of ASN1_STRING */ -char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method, const WOLFSSL_ASN1_STRING *s) +char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method, + const WOLFSSL_ASN1_STRING *s) { int i; int tmpSz = 100; @@ -23205,6 +23369,7 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void) XMEMSET(a, 0, sizeof(WOLFSSL_ASN1_INTEGER)); a->data = a->intData; a->dataMax = WOLFSSL_ASN1_INTEGER_MAX; + a->length = 0; return a; } @@ -23301,6 +23466,8 @@ int wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v) /* Set length */ a->data[i++] = (unsigned char)((j == 0) ? ++j : j); + /* +2 for type and length */ + a->length = j + 2; /* Copy to data */ for (; j > 0; j--) { @@ -23339,6 +23506,7 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) a->data[i++] = ASN_INTEGER; i += SetLength(x509->serialSz, a->data + i); XMEMCPY(&a->data[i], x509->serial, x509->serialSz); + a->length = x509->serialSz + 2; x509->serialNumber = a; @@ -25382,7 +25550,6 @@ int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, return -2; } else { - word32 i; word32 sz = sizeof(WOLFSSL_DES_key_schedule); /* sanity check before call to DES_check */ @@ -25392,19 +25559,9 @@ int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes, } /* check odd parity */ - for (i = 0; i < sz; i++) { - unsigned char c = *((unsigned char*)myDes + i); - if (((c & 0x01) ^ - ((c >> 1) & 0x01) ^ - ((c >> 2) & 0x01) ^ - ((c >> 3) & 0x01) ^ - ((c >> 4) & 0x01) ^ - ((c >> 5) & 0x01) ^ - ((c >> 6) & 0x01) ^ - ((c >> 7) & 0x01)) != 1) { - WOLFSSL_MSG("Odd parity test fail"); - return -1; - } + if (wolfSSL_DES_check_key_parity(myDes) != 1) { + WOLFSSL_MSG("Odd parity test fail"); + return -1; } if (wolfSSL_DES_is_weak_key(myDes) == 1) { @@ -25518,7 +25675,7 @@ void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes) WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity"); for (i = 0; i < sz; i++) { - unsigned char c = *((unsigned char*)myDes + i); + unsigned char c = (*myDes)[i]; if (( ((c >> 1) & 0x01) ^ ((c >> 2) & 0x01) ^ @@ -25526,13 +25683,35 @@ void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes) ((c >> 4) & 0x01) ^ ((c >> 5) & 0x01) ^ ((c >> 6) & 0x01) ^ - ((c >> 7) & 0x01)) != 1) { - WOLFSSL_MSG("Setting odd parity bit"); - *((unsigned char*)myDes + i) = *((unsigned char*)myDes + i) | 0x01; + ((c >> 7) & 0x01)) == (c & 0x01)) { + WOLFSSL_MSG("Flipping parity bit"); + (*myDes)[i] = c ^ 0x01; } } } +int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *myDes) +{ + word32 i; + word32 sz = sizeof(WOLFSSL_DES_cblock); + + WOLFSSL_ENTER("wolfSSL_DES_check_key_parity"); + + for (i = 0; i < sz; i++) { + unsigned char c = (*myDes)[i]; + if (( + ((c >> 1) & 0x01) ^ + ((c >> 2) & 0x01) ^ + ((c >> 3) & 0x01) ^ + ((c >> 4) & 0x01) ^ + ((c >> 5) & 0x01) ^ + ((c >> 6) & 0x01) ^ + ((c >> 7) & 0x01)) == (c & 0x01)) { + return 0; + } + } + return 1; +} #ifdef WOLFSSL_DES_ECB /* Encrypt or decrypt input message desa with key and get output in desb. @@ -25569,7 +25748,6 @@ void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa, } } #endif - #endif /* NO_DES3 */ #ifndef NO_RC4 @@ -26079,10 +26257,6 @@ int wolfSSL_sk_num(WOLFSSL_STACK* sk) void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i) { - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - int offset = i; - WOLFSSL_GENERAL_NAME* gn; - #endif WOLFSSL_ENTER("wolfSSL_sk_value"); for (; sk != NULL && i > 0; i--) @@ -26093,38 +26267,24 @@ void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i) switch (sk->type) { case STACK_TYPE_X509: return (void*)sk->data.x509; - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) case STACK_TYPE_CIPHER: - sk->data.cipher.offset = offset; + #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + sk->data.cipher.offset = i; + #endif return (void*)&sk->data.cipher; case STACK_TYPE_GEN_NAME: - gn = (WOLFSSL_GENERAL_NAME*)sk->data.obj; - if (gn == NULL) - return NULL; - gn->type = sk->data.obj->type; - gn->d.ia5 = sk->data.obj->d.ia5; - gn->d.iPAddress = sk->data.obj->d.iPAddress; - gn->d.dNSName = sk->data.obj->d.dNSName; - gn->d.uniformResourceIdentifier = - sk->data.obj->d.uniformResourceIdentifier; - return (void*)gn; + return (void*)sk->data.gn; case STACK_TYPE_ACCESS_DESCRIPTION: return (void*)sk->data.access; - #endif case STACK_TYPE_OBJ: return (void*)sk->data.obj; - break; - case STACK_TYPE_NULL: - return (void*)sk->data.generic; - break; - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) case STACK_TYPE_X509_EXT: return (void*)sk->data.ext; - #endif case STACK_TYPE_CONF_VALUE: return (void*)sk->data.conf->value; + case STACK_TYPE_NULL: default: - return (void*)sk->data.obj; + return (void*)sk->data.generic; } } @@ -26139,24 +26299,28 @@ void wolfSSL_sk_free(WOLFSSL_STACK* sk) } switch (sk->type) { - #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) case STACK_TYPE_X509: wolfSSL_sk_X509_free(sk); break; + #if defined(OPENSSL_ALL) case STACK_TYPE_CIPHER: wolfSSL_sk_CIPHER_free(sk); break; + #endif case STACK_TYPE_GEN_NAME: - wolfSSL_sk_ASN1_OBJECT_free(sk); + wolfSSL_sk_GENERAL_NAME_free(sk); break; + #if defined(OPENSSL_ALL) || defined (WOLFSSL_QT) case STACK_TYPE_ACCESS_DESCRIPTION: - wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk,NULL); + wolfSSL_sk_ACCESS_DESCRIPTION_free(sk); break; + #endif case STACK_TYPE_OBJ: wolfSSL_sk_ASN1_OBJECT_free(sk); break; - case STACK_TYPE_NULL: - wolfSSL_sk_GENERIC_free(sk); + #ifdef OPENSSL_ALL + case STACK_TYPE_X509_INFO: + wolfSSL_sk_X509_INFO_free(sk); break; case STACK_TYPE_X509_NAME: wolfSSL_sk_X509_NAME_free(sk); @@ -26164,15 +26328,17 @@ void wolfSSL_sk_free(WOLFSSL_STACK* sk) case STACK_TYPE_CONF_VALUE: wolfSSL_sk_CONF_VALUE_free(sk); break; - #endif - default: - wolfSSL_sk_ASN1_OBJECT_free(sk); + #endif + case STACK_TYPE_NULL: + default: + wolfSSL_sk_GENERIC_free(sk); } } /* Frees each node in the stack and frees the stack. * Does not free any internal members of the stack nodes. */ -void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) +void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, + void (*f) (void*)) { WOLFSSL_STACK* node; WOLFSSL_STACK* tmp; @@ -26186,6 +26352,9 @@ void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) while (node) { tmp = node; node = node->next; + if (f) + f(tmp->data.generic); + tmp->data.generic = NULL; XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); } @@ -26193,25 +26362,30 @@ void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); } +void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) +{ + wolfSSL_sk_GENERIC_pop_free(sk, NULL); +} + /* Free all nodes in a stack */ void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, wolfSSL_sk_freefunc func) { - int type; WOLFSSL_ENTER("wolfSSL_sk_pop_free"); if (sk == NULL) { WOLFSSL_MSG("Error, BAD_FUNC_ARG"); return; } - type = sk->type; - switch(type) { - #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + + switch(sk->type) { + #if defined(OPENSSL_ALL) || defined (WOLFSSL_QT) case STACK_TYPE_ACCESS_DESCRIPTION: wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, (void (*)(WOLFSSL_ACCESS_DESCRIPTION*))func); break; + #endif case STACK_TYPE_X509: wolfSSL_sk_X509_pop_free(sk,(void (*)(WOLFSSL_X509*))func); break; @@ -26220,11 +26394,28 @@ void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, (void (*)(WOLFSSL_ASN1_OBJECT*))func); break; case STACK_TYPE_GEN_NAME: + wolfSSL_sk_GENERAL_NAME_pop_free(sk, + (void (*)(WOLFSSL_GENERAL_NAME*))func); break; - #endif + #ifdef OPENSSL_ALL + case STACK_TYPE_X509_NAME: + wolfSSL_sk_X509_NAME_pop_free(sk, + (void (*)(WOLFSSL_X509_NAME*))func); + break; + case STACK_TYPE_X509_EXT: + wolfSSL_sk_X509_EXTENSION_pop_free(sk, + (void (*)(WOLFSSL_X509_EXTENSION*))func); + break; + #endif + #if defined(OPENSSL_ALL) + case STACK_TYPE_X509_INFO: + wolfSSL_sk_X509_INFO_pop_free(sk, + (void (*)(WOLFSSL_X509_INFO*))func); + break; + #endif default: - wolfSSL_sk_ASN1_OBJECT_pop_free(sk, - (void (*)(WOLFSSL_ASN1_OBJECT*))func); + wolfSSL_sk_GENERIC_pop_free(sk, + (void (*)(void*))func); break; } } @@ -28920,6 +29111,12 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa) } #endif /* !NO_RSA && !HAVE_USER_RSA */ +WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void) +{ + return (WOLFSSL_HMAC_CTX*)XMALLOC(sizeof(WOLFSSL_HMAC_CTX), NULL, + DYNAMIC_TYPE_OPENSSL); +} + int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx) { WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init"); @@ -29342,6 +29539,24 @@ int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx) } +void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx) +{ + if (!ctx) { + return; + } + wolfSSL_HMAC_cleanup(ctx); + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); +} + +size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx) +{ + if (!ctx) { + return 0; + } + + return (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType); +} + const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) { WOLFSSL_MSG("wolfSSL_get_digestbynid"); @@ -29364,6 +29579,14 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) #ifndef NO_RSA +WOLFSSL_RSA* wolfSSL_EVP_PKEY_get0_RSA(WOLFSSL_EVP_PKEY *pkey) +{ + if (!pkey) { + return NULL; + } + return pkey->rsa; +} + WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key) { WOLFSSL_RSA* local; @@ -29425,7 +29648,7 @@ int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key) #endif return WOLFSSL_SUCCESS; } -#endif /* NO_RSA */ +#endif /* !NO_RSA */ #ifndef NO_WOLFSSL_STUB WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key) @@ -29437,16 +29660,29 @@ WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key) } #endif -#ifndef NO_WOLFSSL_STUB -WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) +WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get0_EC_KEY(WOLFSSL_EVP_PKEY *pkey) { - (void)key; - WOLFSSL_STUB("EVP_PKEY_get1_EC_KEY"); - WOLFSSL_MSG("wolfSSL_EVP_PKEY_get1_EC_KEY not implemented"); - - return NULL; + WOLFSSL_EC_KEY *eckey = NULL; + if (pkey) { + #ifdef HAVE_ECC + eckey = pkey->ecc; + #endif + } + return eckey; +} + +WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* pkey) +{ + WOLFSSL_EC_KEY *eckey = NULL; + if (pkey) { + /* increment reference count */ + pkey->references++; + #ifdef HAVE_ECC + eckey = pkey->ecc; + #endif + } + return eckey; } -#endif void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx) { @@ -31223,6 +31459,34 @@ int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group, return WOLFSSL_SUCCESS; } + +int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group) +{ + int ret; + int order_bits = 0; + mp_int order; + + if (group == NULL || group->curve_idx < 0) { + WOLFSSL_MSG("wolfSSL_EC_GROUP_order_bits NULL error"); + return 0; + } + + ret = mp_init(&order); + if (ret == 0) { + ret = mp_read_radix(&order, ecc_sets[group->curve_idx].order, + MP_RADIX_HEX); + if (ret == 0) + ret = mp_unsigned_bin_size(&order); + if (ret >= 0) + ret = mp_to_unsigned_bin(&order, (byte*)&order_bits); + if (ret == 0) + ret = order_bits; + mp_clear(&order); + } + + return ret; +} + /* End EC_GROUP */ /* Start EC_POINT */ @@ -31527,6 +31791,29 @@ int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, /* End EC_POINT */ +size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_builtin_curve *r, size_t nitems) +{ + static size_t ecc_sets_count = 0; + size_t i, min; + + if (ecc_sets_count == 0) { + for (i = 0; ecc_sets[i].size != 0; i++); + ecc_sets_count = i; + } + + if (r == NULL || nitems == 0) + return ecc_sets_count; + + min = nitems < ecc_sets_count ? nitems : ecc_sets_count; + + for (i = 0; i < min; i++) { + r[i].nid = ecc_sets[i].id; + r[i].comment = ecc_sets[i].name; + } + + return ecc_sets_count; +} + /* Start ECDSA_SIG */ void wolfSSL_ECDSA_SIG_free(WOLFSSL_ECDSA_SIG *sig) { @@ -32996,6 +33283,102 @@ int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf, return WOLFSSL_SUCCESS; } + +WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags) +{ + int name_len; + WOLFSSL_RSA_METHOD* meth; + + meth = (WOLFSSL_RSA_METHOD*)XMALLOC(sizeof(WOLFSSL_RSA_METHOD), NULL, + DYNAMIC_TYPE_OPENSSL); + name_len = (int)XSTRLEN(name); + if (!meth) { + return NULL; + } + meth->flags = flags; + meth->name = (char*)XMALLOC(name_len+1, NULL, DYNAMIC_TYPE_OPENSSL); + if (!meth->name) { + XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL); + return NULL; + } + XMEMCPY(meth->name, name, name_len+1); + WOLFSSL_MSG("RSA_METHOD is not implemented."); + return meth; +} + +void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth) +{ + if (meth) { + XFREE(meth->name, NULL, DYNAMIC_TYPE_OPENSSL); + XFREE(meth, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *rsa, void* p) +{ + (void)rsa; + (void)p; + WOLFSSL_MSG("RSA_METHOD is not implemented."); + return 1; +} + +#if defined(OPENSSL_EXTRA) +int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth) +{ + rsa->meth = meth; + return 1; +} + +const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa) +{ + if (!rsa) { + return NULL; + } + return rsa->meth; +} + +int wolfSSL_RSA_flags(const WOLFSSL_RSA *r) +{ + if (r && r->meth) { + return r->meth->flags; + } else { + return 0; + } +} + +void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags) +{ + if (r && r->meth) { + r->meth->flags = flags; + } +} +#endif /* OPENSSL_EXTRA */ + +int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, + WOLFSSL_BIGNUM *d) +{ + /* If the fields n and e in r are NULL, the corresponding input + * parameters MUST be non-NULL for n and e. d may be + * left NULL (in case only the public key is used). + */ + if ((!r->n && !n) || (!r->e && !e)) + return 0; + + if (n) { + wolfSSL_BN_free(r->n); + r->n = n; + } + if (e) { + wolfSSL_BN_free(r->e); + r->e = e; + } + if (d) { + wolfSSL_BN_clear_free(r->d); + r->d = d; + } + + return 1; +} #endif /* NO_RSA */ #ifdef OPENSSL_EXTRA @@ -33028,7 +33411,7 @@ int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf, int derSz return WOLFSSL_SUCCESS; } -#endif /* NO_DSA */ +#endif /* !NO_DSA */ #ifdef HAVE_ECC /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ @@ -33652,10 +34035,10 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) #endif -#ifdef OPENSSL_EXTRA /*Lighttp compatibility*/ - +#ifdef OPENSSL_EXTRA #ifndef NO_CERTS - void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name){ + void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name) + { WOLFSSL_ENTER("wolfSSL_X509_NAME_free"); FreeX509Name(name, NULL); XFREE(name, NULL, DYNAMIC_TYPE_X509); @@ -33682,9 +34065,9 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) /* Creates a duplicate of a WOLFSSL_X509_NAME structure. Returns a new WOLFSSL_X509_NAME structure or NULL on failure */ - WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME* name) + WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME *name) { - WOLFSSL_X509_NAME* dup; + WOLFSSL_X509_NAME* dup = NULL; WOLFSSL_ENTER("wolfSSL_X509_NAME_dup"); @@ -33693,34 +34076,51 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return NULL; } - dup = (WOLFSSL_X509_NAME*)XMALLOC(sizeof(WOLFSSL_X509_NAME), NULL, - DYNAMIC_TYPE_X509); - if (dup == NULL) { - WOLFSSL_MSG("Malloc error"); + if (!(dup = wolfSSL_X509_NAME_new())) { return NULL; } - XMEMCPY(dup, name, sizeof(WOLFSSL_X509_NAME)); - InitX509Name(dup, 1); - XMEMCPY(dup->name, name->name, name->sz); - dup->sz = name->sz; - dup->dynamicName = name->dynamicName; - #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - dup->fullName.fullName = (char*)XMALLOC(name->fullName.fullNameLen, - NULL, DYNAMIC_TYPE_X509); - if (dup->fullName.fullName != NULL) - XMEMCPY(dup->fullName.fullName, name->fullName.fullName, - name->fullName.fullNameLen); - dup->x509 = name->x509; - #endif - #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) - dup->rawLen = min(name->rawLen, sizeof(dup->raw)); - XMEMCPY(dup->raw, name->raw, dup->rawLen); - #endif + /* copy contents */ + XMEMCPY(dup, name, sizeof(WOLFSSL_X509_NAME)); + + /* handle dynamic portions */ + if (name->dynamicName) { + if (!(dup->name = (char*)XMALLOC(name->sz, 0, + DYNAMIC_TYPE_OPENSSL))) { + goto err; + } + XMEMCPY(dup->name, name->name, name->sz); + } + #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ + !defined(NO_ASN) + if (!(dup->fullName.fullName = (char*)XMALLOC(name->fullName.fullNameLen, + 0, DYNAMIC_TYPE_OPENSSL))) { + goto err; + } + XMEMCPY(dup->fullName.fullName, name->fullName.fullName, + name->fullName.fullNameLen); + #endif return dup; - } + err: + if (dup) { + if (dup->dynamicName && dup->name) { + XFREE(dup->name, 0, DYNAMIC_TYPE_OPENSSL); + dup->name = NULL; + } + #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ + !defined(NO_ASN) + if (dup->fullName.fullName && + dup->fullName.fullName != name->fullName.fullName) { + XFREE(dup->fullName.fullName, 0, DYNAMIC_TYPE_OPENSSL); + dup->fullName.fullName = NULL; + } + #endif + wolfSSL_X509_NAME_free(dup); + } + return NULL; + } #if defined(WOLFSSL_CERT_GEN) /* helper function for CopyX509NameToCertName() @@ -34376,7 +34776,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) /* Compares the two X509 names. If the size of x is larger then y then a * positive value is returned if x is smaller a negative value is returned. - * In the case that the sizes are equal a the value of memcmp between the + * In the case that the sizes are equal a the value of strcmp between the * two names is returned. * * x First name for comparison @@ -34385,19 +34785,31 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x, const WOLFSSL_X509_NAME* y) { - WOLFSSL_STUB("wolfSSL_X509_NAME_cmp"); + const char* _x; + const char* _y; + WOLFSSL_ENTER("wolfSSL_X509_NAME_cmp"); if (x == NULL || y == NULL) { WOLFSSL_MSG("Bad argument passed in"); return -2; } - if ((x->sz - y->sz) != 0) { + if (x == y) { + return 0; /* match */ + } + + if (x->sz != y->sz) { return x->sz - y->sz; } - else { - return XMEMCMP(x->name, y->name, x->sz); /* y sz is the same */ - } + + /* + * If the name member is not set or is immediately null terminated then + * compare the staticName member + */ + _x = (x->name && *x->name) ? x->name : x->staticName; + _y = (y->name && *y->name) ? y->name : y->staticName; + + return XSTRNCMP(_x, _y, x->sz); /* y sz is the same */ } @@ -34418,39 +34830,9 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return NULL; } - if (bp->type == WOLFSSL_BIO_MEMORY) { - l = (long)wolfSSL_BIO_ctrl_pending(bp); - if (l <= 0) { - WOLFSSL_MSG("No pending data in WOLFSSL_BIO"); - return NULL; - } - } - else if (bp->type == WOLFSSL_BIO_FILE) { -#ifndef NO_FILESYSTEM - /* Read in next certificate from file but no more. */ - i = XFTELL((XFILE)bp->ptr); - if (i < 0) - return NULL; - if (XFSEEK((XFILE)bp->ptr, 0, XSEEK_END) != 0) - return NULL; - l = XFTELL((XFILE)bp->ptr); - if (l < 0) - return NULL; - if (XFSEEK((XFILE)bp->ptr, i, SEEK_SET) != 0) - return NULL; - - /* check calculated length */ - if (l - i < 0) - return NULL; - - l -= i; -#else - WOLFSSL_MSG("Unable to read file with NO_FILESYSTEM defined"); + if ((l = wolfSSL_BIO_get_len(bp)) <= 0) { return NULL; -#endif /* !NO_FILESYSTEM */ } - else - return NULL; pem = (unsigned char*)XMALLOC(l, 0, DYNAMIC_TYPE_PEM); if (pem == NULL) @@ -34499,6 +34881,59 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return x509; } + WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp, + WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u) + { +#if defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_CRL) + unsigned char* pem = NULL; + int pemSz; + int derSz; + DerBuffer* der = NULL; + WOLFSSL_X509_CRL* crl = NULL; + + if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) { + goto err; + } + + pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM); + if (pem == NULL) { + goto err; + } + + if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) { + goto err; + } + + if((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) { + goto err; + } + derSz = der->length; + if((crl = wolfSSL_d2i_X509_CRL(x, der->buffer, derSz)) == NULL) { + goto err; + } + +err: + if(pem != NULL) { + XFREE(pem, 0, DYNAMIC_TYPE_PEM); + } + if(der != NULL) { + FreeDer(&der); + } + + (void)cb; + (void)u; + + return crl; +#else + (void)bp; + (void)x; + (void)cb; + (void)u; + + return NULL; +#endif + } + #if !defined(NO_FILESYSTEM) static void* wolfSSL_PEM_read_X509_ex(XFILE fp, void **x, pem_password_cb *cb, void *u, int type) @@ -34507,6 +34942,8 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) int pemSz; long i = 0, l; void *newx509; + int derSz; + DerBuffer* der = NULL; WOLFSSL_ENTER("wolfSSL_PEM_read_X509"); @@ -34546,8 +34983,6 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) #ifdef HAVE_CRL case CRL_TYPE: { - int derSz; - DerBuffer* der = NULL; if((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0) goto err_exit; derSz = der->length; @@ -34571,10 +35006,13 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) err_exit: if(pem != NULL) XFREE(pem, 0, DYNAMIC_TYPE_PEM); + if(der != NULL) + FreeDer(&der); return NULL; (void)cb; (void)u; + (void)derSz; } @@ -35450,7 +35888,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) } else { for (i = 0; i < MAX_NAME_ENTRIES; i++) { - if (name->extra[i].set != 1) { /* not set so overwrited */ + if (name->extra[i].set != 1) { /* not set so overwritten */ WOLFSSL_X509_NAME_ENTRY* current = &(name->extra[i]); WOLFSSL_ASN1_STRING* str; @@ -35659,21 +36097,18 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) "Cert OCSP sign key", "OCSP Signing"}, /* oidCertNameType */ - { NID_commonName, NID_commonName, oidCertNameType, "commonName", - "commonName"}, - { NID_surname, NID_surname, oidCertNameType, "surname", "surname"}, + { NID_commonName, NID_commonName, oidCertNameType, "CN", "commonName"}, + { NID_surname, NID_surname, oidCertNameType, "SN", "surname"}, { NID_serialNumber, NID_serialNumber, oidCertNameType, "serialNumber", "serialNumber"}, - { NID_countryName, NID_countryName, oidCertNameType, "countryName", - "countryName"}, - { NID_localityName, NID_localityName, oidCertNameType, "localityName", - "localityName"}, - { NID_stateOrProvinceName, NID_stateOrProvinceName, oidCertNameType, - "stateOrProvinceName", "stateOrProvinceName"}, - { NID_organizationName, NID_organizationName, oidCertNameType, - "organizationName", "organizationName"}, - { NID_organizationalUnitName, NID_organizationalUnitName, - oidCertNameType, "organizationalUnitName", "organizationUnitName"}, + { NID_countryName, NID_countryName, oidCertNameType, "C", "countryName"}, + { NID_localityName, NID_localityName, oidCertNameType, "L", "localityName"}, + { NID_stateOrProvinceName, NID_stateOrProvinceName, oidCertNameType, "ST", + "stateOrProvinceName"}, + { NID_organizationName, NID_organizationName, oidCertNameType, "O", + "organizationName"}, + { NID_organizationalUnitName, NID_organizationalUnitName, oidCertNameType, + "OU", "organizationUnitName"}, { NID_emailAddress, NID_emailAddress, oidCertNameType, "emailAddress", "emailAddress"}, #endif @@ -35753,10 +36188,9 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) const unsigned char *bytes, int len, int loc, int set) { - int ret; - int i; + int ret = WOLFSSL_FAILURE; + int nid; WOLFSSL_X509_NAME_ENTRY* entry; - size_t fieldSz; (void)type; WOLFSSL_ENTER("wolfSSL_X509_NAME_add_entry_by_txt"); @@ -35764,22 +36198,17 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) if (name == NULL || field == NULL) return WOLFSSL_FAILURE; - fieldSz = XSTRLEN(field); - for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) { - if (XSTRNCMP(field, wolfssl_object_info[i].sName, fieldSz) == 0) - break; - } - - if (i == WOLFSSL_OBJECT_INFO_SZ) + if ((nid = wolfSSL_OBJ_txt2nid(field)) == NID_undef) return WOLFSSL_FAILURE; entry = wolfSSL_X509_NAME_ENTRY_create_by_NID(NULL, - wolfssl_object_info[i].nid, type, (unsigned char*)bytes, len); + nid, type, (unsigned char*)bytes, len); if (entry == NULL) return WOLFSSL_FAILURE; ret = wolfSSL_X509_NAME_add_entry(name, entry, loc, set); wolfSSL_X509_NAME_ENTRY_free(entry); + return ret; } @@ -35897,6 +36326,30 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return obj; } + static const char* oid_translate_num_to_str(const char* oid) + { + const struct oid_dict { + const char* num; + const char* desc; + } oid_dict[] = { + { "2.5.29.37.0", "Any Extended Key Usage" }, + { "1.3.6.1.5.5.7.3.1", "TLS Web Server Authentication" }, + { "1.3.6.1.5.5.7.3.2", "TLS Web Client Authentication" }, + { "1.3.6.1.5.5.7.3.3", "Code Signing" }, + { "1.3.6.1.5.5.7.3.4", "E-mail Protection" }, + { "1.3.6.1.5.5.7.3.8", "Time Stamping" }, + { "1.3.6.1.5.5.7.3.9", "OCSP Signing" }, + { NULL, NULL } + }; + const struct oid_dict* idx; + + for (idx = oid_dict; idx->num != NULL; idx++) { + if (!XSTRNCMP(oid, idx->num, XSTRLEN(idx->num))) { + return idx->desc; + } + } + return NULL; + } /* if no_name is one than use numerical form otherwise can be short name. * @@ -35905,6 +36358,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, WOLFSSL_ASN1_OBJECT *a, int no_name) { int bufSz; + const char* desc; WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt()"); @@ -35953,13 +36407,82 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) else { bufSz = bufLen - 1; } - XMEMCPY(buf, a->sName, bufSz); + if (bufSz) { + XMEMCPY(buf, a->sName, bufSz); + } + else if (wolfSSL_OBJ_obj2txt(buf, bufLen, a, 1)) { + if ((desc = oid_translate_num_to_str(buf))) { + bufSz = (int)XSTRLEN(desc); + XMEMCPY(buf, desc, min(bufSz, bufLen)); + } + } + else if (a->type == GEN_DNS || a->type == GEN_EMAIL || a->type == GEN_URI) { + bufSz = (int)XSTRLEN((const char*)a->obj); + XMEMCPY(buf, a->obj, min(bufSz, bufLen)); + } } buf[bufSz] = '\0'; return bufSz; } -#endif /* !WOLFCRYPT_ONLY */ +#endif /* OPENSSL_EXTRA */ + +#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ + !defined(NO_ASN) + /* DN_Tags to strings */ + static const struct DN_Tag_Strings { + enum DN_Tags tag; + const char* str; + } dn_tag_strings[] = { + { ASN_COMMON_NAME, "CN" }, + { ASN_SUR_NAME, "SN" }, + { ASN_SERIAL_NUMBER, "serialNumber" }, + { ASN_COUNTRY_NAME, "C" }, + { ASN_LOCALITY_NAME, "L" }, + { ASN_STATE_NAME, "ST" }, + { ASN_ORG_NAME, "O"}, + { ASN_ORGUNIT_NAME, "OU"}, + { ASN_BUS_CAT, "businessCategory"}, + { ASN_EMAIL_NAME, "emailAddress"}, + { ASN_USER_ID, "UID"}, + { ASN_DOMAIN_COMPONENT, "DC"}, + { ASN_DN_NULL, NULL } + }; + + int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name, + const WOLFSSL_ASN1_OBJECT *obj, + int idx) { + const struct DN_Tag_Strings* dn; + enum DN_Tags tag = ASN_DN_NULL; + + if (!name || idx >= name->fullName.locSz || + !obj || !obj->obj) { + return -1; + } + + if (idx < 0) { + idx = 0; + } + for (dn = dn_tag_strings; dn->str != NULL; dn++) { + /* Find the DN_Tags number for the name */ + if (XSTRNCMP((const char*) obj->sName, dn->str, obj->objSz - 1) == 0) { + tag = dn->tag; + break; + } + } + if (!tag) { + /* Unable to identify desired name */ + return -1; + } + for (idx++; idx < name->fullName.locSz; idx++) { + /* Find index of desired name */ + if ((enum DN_Tags)name->fullName.loc[idx] == tag) { + return idx; + } + } + return -1; + } +#endif #if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \ defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \ @@ -36324,7 +36847,6 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return WOLFSSL_FATAL_ERROR; } -#ifdef WOLFSSL_CERT_EXT /* Gets the NID value that is related to the OID string passed in. Example * string would be "2.5.29.14" for subject key ID. * @@ -36332,10 +36854,13 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) */ int wolfSSL_OBJ_txt2nid(const char* s) { + unsigned int i; + #ifdef WOLFSSL_CERT_EXT int ret; - unsigned int i, sum = 0; + unsigned int sum = 0; unsigned int outSz = MAX_OID_SZ; unsigned char out[MAX_OID_SZ]; + #endif WOLFSSL_ENTER("OBJ_txt2nid"); @@ -36343,6 +36868,7 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return NID_undef; } + #ifdef WOLFSSL_CERT_EXT ret = EncodePolicyOID(out, &outSz, s, NULL); if (ret == 0) { /* sum OID */ @@ -36350,16 +36876,19 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) sum += out[i]; } } + #endif /* WOLFSSL_CERT_EXT */ /* get the group that the OID's sum is in * @TODO possible conflict with multiples */ for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) { int len; + #ifdef WOLFSSL_CERT_EXT if (ret == 0) { if (wolfssl_object_info[i].id == (int)sum) { return wolfssl_object_info[i].nid; } } + #endif /* try as a short name */ len = (int)XSTRLEN(s); @@ -36375,7 +36904,6 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return NID_undef; } -#endif /* WOLFSSL_CERT_EXT */ /* Creates new ASN1_OBJECT from short name, long name, or text * representation of oid. If no_name is 0, then short name, long name, and @@ -36412,12 +36940,12 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) are correct */ for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) { /* Short name, long name, and numerical value are interpreted */ - if (((XSTRNCMP(s, wolfssl_object_info[i].sName, len) == 0) || - (XSTRNCMP(s, wolfssl_object_info[i].lName, len) == 0) || - (wolfssl_object_info[i].id == (int)sum)) && no_name == 0) + if (no_name == 0 && ((XSTRNCMP(s, wolfssl_object_info[i].sName, len) == 0) || + (XSTRNCMP(s, wolfssl_object_info[i].lName, len) == 0) || + (wolfssl_object_info[i].id == (int)sum))) nid = wolfssl_object_info[i].nid; /* Only numerical value is interpreted */ - else if (wolfssl_object_info[i].id == (int)sum && no_name == 1) + else if (no_name == 1 && wolfssl_object_info[i].id == (int)sum) nid = wolfssl_object_info[i].nid; } @@ -36614,7 +37142,8 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) } #ifndef NO_WOLFSSL_STUB - int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key){ + int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key) + { (void) x509; (void) key; WOLFSSL_ENTER("wolfSSL_X509_check_private_key"); @@ -36623,16 +37152,20 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) return WOLFSSL_SUCCESS; } - WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk ){ + WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( + WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk) + { (void) sk; WOLFSSL_ENTER("wolfSSL_dup_CA_list"); WOLFSSL_STUB("SSL_dup_CA_list"); return NULL; } + #endif -#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */ +#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || + HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */ #endif /* OPENSSL_EXTRA */ #ifndef WOLFCRYPT_ONLY @@ -36648,7 +37181,8 @@ unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line) (void)line; (void)file; -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(DEBUG_WOLFSSL) || defined(WOLFSSL_HAPROXY) +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(DEBUG_WOLFSSL) || \ + defined(WOLFSSL_HAPROXY) { int ret; @@ -38172,6 +38706,12 @@ void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info) wolfSSL_X509_free(info->x509); info->x509 = NULL; } +#ifdef HAVE_CRL + if (info->crl) { + wolfSSL_X509_CRL_free(info->crl); + info->crl = NULL; + } +#endif wolfSSL_X509_PKEY_free(info->x_pkey); info->x_pkey = NULL; @@ -38181,7 +38721,11 @@ void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info) WOLFSSL_STACK* wolfSSL_sk_X509_INFO_new_null(void) { - return wolfSSL_sk_new_node(NULL); + WOLFSSL_STACK* sk = wolfSSL_sk_new_node(NULL); + if (sk) { + sk->type = STACK_TYPE_X509_INFO; + } + return sk; } @@ -38236,6 +38780,7 @@ WOLF_STACK_OF(WOLFSSL_CIPHER)* wolfSSL_sk_SSL_CIPHER_dup( for (i = 0; i < sz && current != NULL; i++) { WOLFSSL_STACK* add = wolfSSL_sk_new_node(in->heap); if (add != NULL) { + add->type = STACK_TYPE_CIPHER; wolfSSL_CIPHER_copy(&(current->data.cipher), &(add->data.cipher)); add->num = i+1; add->next = ret; @@ -38319,50 +38864,47 @@ WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk #if defined(OPENSSL_ALL) void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, - void f (WOLFSSL_X509_INFO*)) -{ - WOLFSSL_X509_INFO* info; - WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free"); - - info = wolfSSL_sk_X509_INFO_pop(sk); - if (info) { - if (f) - f(info); - else - wolfSSL_X509_INFO_free(info); - } - wolfSSL_sk_free_node(sk); -} - -void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk) + void (*f) (WOLFSSL_X509_INFO*)) { WOLFSSL_STACK* node; + WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_pop_free"); + if (sk == NULL) { return; } /* parse through stack freeing each node */ node = sk->next; - while (sk->num > 1) { + while (node && sk->num > 1) { WOLFSSL_STACK* tmp = node; node = node->next; - wolfSSL_X509_INFO_free(tmp->data.info); + if (f) + f(tmp->data.info); + else + wolfSSL_X509_INFO_free(tmp->data.info); tmp->data.info = NULL; - XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); sk->num -= 1; } /* free head of stack */ if (sk->num == 1) { - wolfSSL_X509_INFO_free(sk->data.info); + if (f) + f(sk->data.info); + else + wolfSSL_X509_INFO_free(sk->data.info); sk->data.info = NULL; } XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); } +void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk) +{ + wolfSSL_sk_X509_INFO_pop_free(sk, NULL); +} + /* Adds the WOLFSSL_X509_INFO to the stack "sk". "sk" takes control of "in" and * tries to free it when the stack is free'd. @@ -38397,6 +38939,7 @@ int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, /* push new obj onto head of stack */ node->data.info = sk->data.info; node->next = sk->next; + node->type = sk->type; sk->next = node; sk->data.info = in; sk->num += 1; @@ -38413,13 +38956,15 @@ WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_sk_X509_NAME_new(wolf_sk_compare_cb cb sk = wolfSSL_sk_new_node(NULL); if (sk != NULL) { + sk->type = STACK_TYPE_X509_NAME; sk->comp = cb; } return sk; } -int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509_NAME* name) +int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, + WOLFSSL_X509_NAME* name) { WOLFSSL_STACK* node; @@ -38457,7 +39002,8 @@ int wolfSSL_sk_X509_NAME_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509 } /* return index of found, or negative to indicate not found */ -int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509_NAME* name) +int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk, + WOLFSSL_X509_NAME *name) { int i; @@ -38466,16 +39012,27 @@ int wolfSSL_sk_X509_NAME_find(const WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSS if (sk == NULL) return BAD_FUNC_ARG; - for (i=0; sk != NULL; i++, sk = sk->next) { - if (sk->data.name == name) { + for (i = 0; sk; i++, sk = sk->next) { + if (wolfSSL_X509_NAME_cmp(sk->data.name, name) == 0) { return i; } } - return -1; } -int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, wolf_sk_compare_cb cb) +int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_num"); + if (s) { + return (int)s->num; + } else { + return 0; + } +} + + +int wolfSSL_sk_X509_NAME_set_cmp_func(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, + wolf_sk_compare_cb cb) { WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_set_cmp_func"); @@ -38505,7 +39062,8 @@ int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *sk) * returns a pointer to a WOLFSSL_X509_NAME structure on success and NULL on * fail */ -WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk, int i) +WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(const STACK_OF(WOLFSSL_X509_NAME)* sk, + int i) { WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_value"); @@ -38548,40 +39106,45 @@ WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk } void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, - void f (WOLFSSL_X509_NAME*)) -{ - WOLFSSL_X509_NAME* name; - WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free"); - - name = wolfSSL_sk_X509_NAME_pop(sk); - if (name) { - if (f) - f(name); - else - wolfSSL_X509_NAME_free(name); - } -} - -/* Free only the sk structure */ -void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) + void (*f) (WOLFSSL_X509_NAME*)) { WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_free"); + WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_pop_free"); if (sk == NULL) return; node = sk->next; - while (sk->num > 1) { + while (node && sk->num > 1) { WOLFSSL_STACK* tmp = node; node = node->next; + if (f) + f(tmp->data.name); + else + wolfSSL_X509_NAME_free(tmp->data.name); + tmp->data.name = NULL; XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); sk->num -= 1; } + /* free head of stack */ + if (sk->num == 1) { + if (f) + f(sk->data.name); + else + wolfSSL_X509_NAME_free(sk->data.name); + sk->data.name = NULL; + } + XFREE(sk, sk->heap, DYNAMIC_TYPE_OPENSSL); } +/* Free only the sk structure */ +void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) +{ + wolfSSL_sk_X509_NAME_pop_free(sk, NULL); +} + #if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) /* Helper function for X509_NAME_print_ex. Sets *buf to string for domain name attribute based on NID. Returns size of buf */ @@ -38863,8 +39426,8 @@ void wolfSSL_THREADID_set_numeric(void* id, unsigned long val) #ifndef NO_WOLFSSL_STUB -WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(WOLFSSL_X509_STORE_CTX* ctx, - WOLFSSL_X509_NAME* name) +WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( + WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name) { WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs"); WOLFSSL_STUB("X509_STORE_get1_certs"); @@ -38872,8 +39435,36 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(WOLFSSL_X509_STORE_CT (void)name; return NULL; } + +WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects( + WOLFSSL_X509_STORE* store) +{ + WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects"); + WOLFSSL_STUB("wolfSSL_X509_STORE_get0_objects"); + (void)store; + return NULL; +} + +WOLFSSL_X509_OBJECT* wolfSSL_sk_X509_OBJECT_delete( + WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i) +{ + WOLFSSL_ENTER("wolfSSL_sk_X509_OBJECT_delete"); + WOLFSSL_STUB("wolfSSL_sk_X509_OBJECT_delete"); + (void)sk; + (void)i; + return NULL; +} + +void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *a) +{ + WOLFSSL_ENTER("wolfSSL_X509_OBJECT_free"); + WOLFSSL_STUB("wolfSSL_X509_OBJECT_free"); + (void)a; +} + #endif + #endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_LIGHTY)) */ @@ -39595,6 +40186,7 @@ WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl) for (i = 0; i < suites->suiteSz; i+=2) { WOLFSSL_STACK* add = wolfSSL_sk_new_node(ssl->heap); if (add != NULL) { + add->type = STACK_TYPE_CIPHER; add->data.cipher.cipherSuite0 = suites->suites[i]; add->data.cipher.cipherSuite = suites->suites[i+1]; @@ -41446,14 +42038,6 @@ void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx) /* do free since static ctx that does nothing */ } -void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn) -{ - WOLFSSL_MSG("wolfSSL_BN_clear_free"); - - wolfSSL_BN_free(bn); -} - - /* WOLFSSL_SUCCESS on ok */ int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b) @@ -43058,14 +43642,12 @@ void wolfSSL_BN_init(WOLFSSL_BIGNUM* bn) } #endif - void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn) { WOLFSSL_MSG("wolfSSL_BN_free"); if (bn) { if (bn->internal) { mp_int* bni = (mp_int*)bn->internal; - mp_forcezero(bni); mp_free(bni); #if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT) XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT); @@ -43076,7 +43658,20 @@ void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn) bn = NULL; } } + +void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn) +{ + WOLFSSL_MSG("wolfSSL_BN_clear_free"); + if (bn) { + if (bn->internal) { + mp_int* bni = (mp_int*)bn->internal; + mp_forcezero(bni); + } + wolfSSL_BN_free(bn); + } +} #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ + #if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa) { @@ -43125,6 +43720,12 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) XFREE(rsa->rng, NULL, DYNAMIC_TYPE_RNG); #endif +#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) + if (rsa->meth) { + wolfSSL_RSA_meth_free(rsa->meth); + } +#endif + InitwolfSSL_Rsa(rsa); /* set back to NULLs for safety */ XFREE(rsa, NULL, DYNAMIC_TYPE_RSA); @@ -43194,7 +43795,7 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) external->inSet = 0; return external; } -#endif /* !NO_RSA && OPENSSL_EXTRA_X509_SMALL */ +#endif /* !NO_RSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) int wolfSSL_EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY* key) diff --git a/tests/api.c b/tests/api.c index 964f1e35e..6d66f54a2 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1837,7 +1837,7 @@ static void test_wolfSSL_ECDSA_SIG(void) /* Test function for wolfSSL_EVP_get_cipherbynid. */ -# if defined(OPENSSL_EXTRA) +#ifdef OPENSSL_EXTRA static void test_wolfSSL_EVP_get_cipherbynid(void) { #ifndef NO_AES @@ -1914,7 +1914,7 @@ static void test_wolfSSL_EVP_get_cipherbynid(void) #else AssertNull(c); #endif -#endif +#endif /* !NO_AES */ #ifndef NO_DES3 AssertNotNull(strcmp("EVP_DES_CBC", wolfSSL_EVP_get_cipherbynid(31))); @@ -1925,7 +1925,7 @@ static void test_wolfSSL_EVP_get_cipherbynid(void) #ifdef WOLFSSL_DES_ECB AssertNotNull(strcmp("EVP_DES_EDE3_ECB", wolfSSL_EVP_get_cipherbynid(33))); #endif -#endif /*NO_DES3*/ +#endif /* !NO_DES3 */ #ifdef HAVE_IDEA AssertNotNull(strcmp("EVP_IDEA_CBC", wolfSSL_EVP_get_cipherbynid(34))); @@ -1935,7 +1935,27 @@ static void test_wolfSSL_EVP_get_cipherbynid(void) AssertNull(wolfSSL_EVP_get_cipherbynid(1)); } -#endif + +static void test_wolfSSL_EVP_CIPHER_CTX() +{ +#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128) + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + const EVP_CIPHER *init = EVP_aes_128_cbc(); + const EVP_CIPHER *test = NULL; + byte key[AES_128_KEY_SIZE] = {0}; + byte iv[AES_IV_SIZE] = {0}; + + AssertNotNull(ctx); + wolfSSL_EVP_CIPHER_CTX_init(ctx); + AssertIntEQ(EVP_CipherInit(ctx, init, key, iv, 1), WOLFSSL_SUCCESS); + test = EVP_CIPHER_CTX_cipher(ctx); + AssertTrue(init == test); + AssertIntEQ(EVP_CIPHER_nid(test), NID_aes_128_cbc); + + EVP_CIPHER_CTX_free(ctx); +#endif /* !NO_AES && HAVE_AES_CBC && WOLFSSL_AES_128 */ +} +#endif /* OPENSSL_EXTRA */ /*----------------------------------------------------------------------------* | IO @@ -4337,7 +4357,7 @@ static void test_wolfSSL_PKCS12(void) WOLFSSL_X509 *cert; WOLFSSL_X509 *x509; WOLFSSL_X509 *tmp; - WOLF_STACK_OF(WOLFSSL_X509) *ca; + STACK_OF(WOLFSSL_X509) *ca; printf(testingFmt, "wolfSSL_PKCS12()"); @@ -4568,6 +4588,61 @@ static void test_wolfSSL_PKCS12(void) #define TEST_PKCS8_ENC #endif +#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) \ + && defined(HAVE_ECC) && defined(WOLFSSL_ENCRYPTED_KEYS) +static WC_INLINE int FailTestCallBack(char* passwd, int sz, int rw, void* userdata) +{ + (void)passwd; + (void)sz; + (void)rw; + (void)userdata; + Fail(("Password callback should not be called by default"), + ("Password callback was called without attempting " + "to first decipher private key without password.")); + return 0; +} +#endif + +static void test_wolfSSL_no_password_cb(void) +{ +#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) && defined(HAVE_PKCS8) \ + && defined(HAVE_ECC) && defined(WOLFSSL_ENCRYPTED_KEYS) + WOLFSSL_CTX* ctx; + byte buffer[FOURK_BUF]; + const char eccPkcs8PrivKeyDerFile[] = "./certs/ecc-privkeyPkcs8.der"; + const char eccPkcs8PrivKeyPemFile[] = "./certs/ecc-privkeyPkcs8.pem"; + XFILE f; + int bytes; + + printf(testingFmt, "test_wolfSSL_no_password_cb()"); + +#ifndef NO_WOLFSSL_CLIENT + AssertNotNull(ctx = wolfSSL_CTX_new(wolfTLS_client_method())); +#else + AssertNotNull(ctx = wolfSSL_CTX_new(wolfTLS_server_method())); +#endif + wolfSSL_CTX_set_default_passwd_cb(ctx, FailTestCallBack); + + AssertTrue((f = XFOPEN(eccPkcs8PrivKeyDerFile, "rb")) != XBADFILE); + bytes = (int)XFREAD(buffer, 1, sizeof(buffer), f); + XFCLOSE(f); + AssertIntLE(bytes, sizeof(buffer)); + AssertIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buffer, bytes, + WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); + + AssertTrue((f = XFOPEN(eccPkcs8PrivKeyPemFile, "rb")) != XBADFILE); + bytes = (int)XFREAD(buffer, 1, sizeof(buffer), f); + XFCLOSE(f); + AssertIntLE(bytes, sizeof(buffer)); + AssertIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buffer, bytes, + WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); + + wolfSSL_CTX_free(ctx); + + printf(resultFmt, passed); +#endif +} + #ifdef TEST_PKCS8_ENC /* for PKCS8 test case */ static WC_INLINE int PKCS8TestCallBack(char* passwd, int sz, int rw, void* userdata) @@ -18447,11 +18522,46 @@ static void test_wolfSSL_X509_NAME(void) AssertIntGT((sz = i2d_X509_NAME((X509_NAME*)b, &tmp)), 0); XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + + AssertNotNull(b = X509_NAME_dup((X509_NAME*)a)); + AssertIntEQ(X509_NAME_cmp(a, b), 0); + X509_NAME_free((X509_NAME*)b); + X509_free(x509); printf(resultFmt, passed); #endif /* defined(OPENSSL_EXTRA) && !defined(NO_DES3) */ } + +static void test_wolfSSL_X509_INFO(void) +{ +#if defined(OPENSSL_ALL) + STACK_OF(X509_INFO) *info_stack; + X509_INFO *info; + BIO *cert; + int i; + + printf(testingFmt, "wolfSSL_X509_INFO"); + + AssertNotNull(cert = BIO_new_file(cliCertFileExt, "r")); + AssertNotNull(info_stack = PEM_X509_INFO_read_bio(cert, NULL, NULL, NULL)); + for (i = 0; i < sk_X509_INFO_num(info_stack); i++) { + AssertNotNull(info = sk_X509_INFO_value(info_stack, i)); + AssertNotNull(info->x509); + AssertNull(info->crl); + } + sk_X509_INFO_pop_free(info_stack, X509_INFO_free); + BIO_free(cert); + + AssertNotNull(cert = BIO_new_file(cliCertFileExt, "r")); + AssertNotNull(info_stack = PEM_X509_INFO_read_bio(cert, NULL, NULL, NULL)); + sk_X509_INFO_free(info_stack); + BIO_free(cert); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_X509_subject_name_hash(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) \ @@ -18501,6 +18611,7 @@ static void test_wolfSSL_DES(void) /* set odd parity for success case */ DES_set_odd_parity(&myDes); + AssertIntEQ(DES_check_key_parity(&myDes), 1); printf("%02x %02x %02x %02x", myDes[0], myDes[1], myDes[2], myDes[3]); AssertIntEQ(DES_set_key_checked(&myDes, &key), 0); for (i = 0; i < sizeof(DES_key_schedule); i++) { @@ -18685,7 +18796,8 @@ static void test_wolfSSL_certs(void) X509* x509; WOLFSSL* ssl; WOLFSSL_CTX* ctx; - WOLF_STACK_OF(ASN1_OBJECT)* sk; + STACK_OF(ASN1_OBJECT)* sk; + ASN1_BIT_STRING* bit_str; int crit; printf(testingFmt, "wolfSSL_certs()"); @@ -18712,7 +18824,7 @@ static void test_wolfSSL_certs(void) #endif /* HAVE_PK_CALLBACKS */ /* create and use x509 */ - x509 = wolfSSL_X509_load_certificate_file(cliCertFile, WOLFSSL_FILETYPE_PEM); + x509 = wolfSSL_X509_load_certificate_file(cliCertFileExt, WOLFSSL_FILETYPE_PEM); AssertNotNull(x509); AssertIntEQ(SSL_use_certificate(ssl, x509), WOLFSSL_SUCCESS); @@ -18746,101 +18858,101 @@ static void test_wolfSSL_certs(void) #endif /* !NO_SHA && !NO_SHA256*/ /* test and checkout X509 extensions */ - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_basic_constraints, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_basic_constraints, &crit, NULL); AssertNotNull(sk); AssertIntEQ(crit, 0); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_key_usage, - &crit, NULL); - /* AssertNotNull(sk); NID not yet supported */ - AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + bit_str = (ASN1_BIT_STRING*)X509_get_ext_d2i(x509, NID_key_usage, &crit, NULL); + AssertNotNull(bit_str); + AssertIntEQ(crit, 1); + AssertIntEQ(bit_str->type, NID_key_usage); + ASN1_BIT_STRING_free(bit_str); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_ext_key_usage, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_ext_key_usage, &crit, NULL); /* AssertNotNull(sk); no extension set */ - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_authority_key_identifier, &crit, NULL); AssertNotNull(sk); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_private_key_usage_period, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_subject_alt_name, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_subject_alt_name, &crit, NULL); /* AssertNotNull(sk); no alt names set */ - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_GENERAL_NAME_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_issuer_alt_name, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_issuer_alt_name, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_info_access, &crit, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_info_access, &crit, NULL); /* AssertNotNull(sk); no auth info set */ - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_sinfo_access, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_sinfo_access, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_name_constraints, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_name_constraints, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_certificate_policies, &crit, NULL); #if !defined(WOLFSSL_SEP) && !defined(WOLFSSL_CERT_EXT) AssertNull(sk); #else /* AssertNotNull(sk); no cert policy set */ #endif - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_policy_mappings, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_policy_mappings, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_policy_constraints, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_policy_constraints, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_inhibit_any_policy, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_inhibit_any_policy, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_tlsfeature, &crit, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_tlsfeature, &crit, NULL); /* AssertNotNull(sk); NID not yet supported */ AssertIntEQ(crit, -1); - wolfSSL_sk_ASN1_OBJECT_free(sk); + sk_ASN1_OBJECT_free(sk); /* test invalid cases */ crit = 0; - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, -1, &crit, NULL); + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, -1, &crit, NULL); AssertNull(sk); AssertIntEQ(crit, -1); - sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(NULL, NID_tlsfeature, + sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(NULL, NID_tlsfeature, NULL, NULL); AssertNull(sk); @@ -20196,7 +20308,7 @@ static void test_wolfSSL_X509_STORE_CTX(void) /* test X509_STORE_CTX_get/set_ex_data */ { int i = 0, tmpData = 5; - int* tmpDataRet; + void* tmpDataRet; AssertNotNull(ctx = X509_STORE_CTX_new()); #if defined(HAVE_EX_DATA) || defined(FORTRESS) for (i = 0; i < MAX_EX_DATA; i++) { @@ -20204,7 +20316,7 @@ static void test_wolfSSL_X509_STORE_CTX(void) WOLFSSL_SUCCESS); tmpDataRet = (int*)X509_STORE_CTX_get_ex_data(ctx, i); AssertNotNull(tmpDataRet); - AssertIntEQ(tmpData, *tmpDataRet); + AssertIntEQ(tmpData, *(int*)tmpDataRet); } #else AssertIntEQ(X509_STORE_CTX_set_ex_data(ctx, i, &tmpData), @@ -20387,18 +20499,27 @@ static void test_wolfSSL_X509_STORE_CTX_get0_store(void) static void test_wolfSSL_CTX_set_client_CA_list(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(NO_CERTS) && \ +#if defined(OPENSSL_ALL) && !defined(NO_RSA) && !defined(NO_CERTS) && \ !defined(NO_WOLFSSL_CLIENT) WOLFSSL_CTX* ctx; - WOLF_STACK_OF(WOLFSSL_X509_NAME)* names = NULL; - WOLF_STACK_OF(WOLFSSL_X509_NAME)* ca_list = NULL; + X509_NAME* name = NULL; + STACK_OF(X509_NAME)* names = NULL; + STACK_OF(X509_NAME)* ca_list = NULL; + int i, names_len; printf(testingFmt, "wolfSSL_CTX_set_client_CA_list()"); AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); - names = wolfSSL_load_client_CA_file(cliCertFile); + names = SSL_load_client_CA_file(cliCertFile); AssertNotNull(names); - wolfSSL_CTX_set_client_CA_list(ctx,names); - AssertNotNull(ca_list = wolfSSL_SSL_CTX_get_client_CA_list(ctx)); + SSL_CTX_set_client_CA_list(ctx,names); + AssertNotNull(ca_list = SSL_CTX_get_client_CA_list(ctx)); + + AssertIntGT((names_len = sk_X509_NAME_num(names)), 0); + for (i=0; i -1); + AssertIntNE(lastpos, -1); + ASN1_OBJECT_free(field_name_obj); + AssertNotNull(x509NameEntry = X509_NAME_get_entry(x509Name, lastpos)); + AssertNotNull(asn1 = X509_NAME_ENTRY_get_data(x509NameEntry)); + AssertIntGE(ASN1_STRING_to_UTF8(&buf_dyn, asn1), 0); + /* + * All Common Names should be www.wolfssl.com + * This makes testing easier as we can test for the expected value. + */ + AssertStrEQ((char*)buf_dyn, "www.wolfssl.com"); + OPENSSL_free(buf_dyn); + AssertTrue((bio = BIO_new(BIO_s_mem())) != NULL); for (j = 0; j < numNames; j++) { @@ -22620,8 +22790,8 @@ static void test_wolfSSL_OBJ_txt2obj(void) static void test_wolfSSL_X509_NAME_ENTRY(void) { - #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) \ - && !defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(WOLFSSL_CERT_GEN) +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \ + !defined(NO_RSA) && defined(WOLFSSL_CERT_GEN) X509* x509; BIO* bio; X509_NAME* nm; @@ -22658,10 +22828,11 @@ static void test_wolfSSL_X509_NAME_ENTRY(void) 0x0c, cn, (int)sizeof(cn))); AssertIntEQ(X509_NAME_add_entry(nm, entry, -1, 0), SSL_SUCCESS); +#ifdef WOLFSSL_CERT_EXT AssertIntEQ(X509_NAME_add_entry_by_txt(nm, "emailAddress", MBSTRING_UTF8, (byte*)"support@wolfssl.com", 19, -1, 1), WOLFSSL_SUCCESS); - +#endif X509_NAME_ENTRY_free(entry); /* Test add entry by NID */ @@ -22672,7 +22843,7 @@ static void test_wolfSSL_X509_NAME_ENTRY(void) X509_free(x509); /* free's nm */ printf(resultFmt, passed); - #endif +#endif } @@ -23382,15 +23553,16 @@ static void test_wolfSSL_sk_GENERAL_NAME(void) #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ !defined(NO_RSA) X509* x509; + GENERAL_NAME* gn; unsigned char buf[4096]; const unsigned char* bufPt; - int bytes; + int bytes, i; XFILE f; STACK_OF(GENERAL_NAME)* sk; printf(testingFmt, "wolfSSL_sk_GENERAL_NAME()"); - f = XFOPEN(cliCertDerFile, "rb"); + f = XFOPEN(cliCertDerFileExt, "rb"); AssertTrue((f != XBADFILE)); AssertIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0); XFCLOSE(f); @@ -23398,38 +23570,25 @@ static void test_wolfSSL_sk_GENERAL_NAME(void) bufPt = buf; AssertNotNull(x509 = d2i_X509(NULL, &bufPt, bytes)); - /* current cert has no alt names */ - AssertNull(sk = (WOLF_STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, + AssertNotNull(sk = (STACK_OF(ASN1_OBJECT)*)X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)); - AssertIntEQ(sk_GENERAL_NAME_num(sk), -1); -#if 0 + AssertIntEQ(sk_GENERAL_NAME_num(sk), 1); for (i = 0; i < sk_GENERAL_NAME_num(sk); i++) { - GENERAL_NAME* gn = sk_GENERAL_NAME_value(sk, i); - if (gn == NULL) { - printf("massive failure\n"); - return -1; - } + AssertNotNull(gn = sk_GENERAL_NAME_value(sk, i)); - if (gn->type == GEN_DNS) { + switch (gn->type) { + case GEN_DNS: printf("found type GEN_DNS\n"); - printf("length = %d\n", gn->d.ia5->length); - printf("data = %s\n", (char*)gn->d.ia5->data); - } - - if (gn->type == GEN_EMAIL) { + break; + case GEN_EMAIL: printf("found type GEN_EMAIL\n"); - printf("length = %d\n", gn->d.ia5->length); - printf("data = %s\n", (char*)gn->d.ia5->data); - } - - if (gn->type == GEN_URI) { + break; + case GEN_URI: printf("found type GEN_URI\n"); - printf("length = %d\n", gn->d.ia5->length); - printf("data = %s\n", (char*)gn->d.ia5->data); + break; } } -#endif X509_free(x509); sk_GENERAL_NAME_pop_free(sk, GENERAL_NAME_free); @@ -23463,13 +23622,28 @@ static void test_wolfSSL_MD4(void) static void test_wolfSSL_RSA(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) && \ + defined(WOLFSSL_KEY_GEN) RSA* rsa; + const BIGNUM *n; + const BIGNUM *e; + const BIGNUM *d; printf(testingFmt, "wolfSSL_RSA()"); AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); AssertIntEQ(RSA_size(rsa), 256); + RSA_get0_key(rsa, &n, &e, &d); + AssertPtrEq(rsa->n, n); + AssertPtrEq(rsa->e, e); + AssertPtrEq(rsa->d, d); + AssertNotNull(n = BN_new()); + AssertNotNull(e = BN_new()); + AssertNotNull(d = BN_new()); + AssertIntEQ(RSA_set0_key(rsa, (BIGNUM*)n, (BIGNUM*)e, (BIGNUM*)d), 1); + AssertPtrEq(rsa->n, n); + AssertPtrEq(rsa->e, e); + AssertPtrEq(rsa->d, d); RSA_free(rsa); #if !defined(USE_FAST_MATH) || (FP_MAX_BITS >= (3072*2)) @@ -23608,6 +23782,45 @@ static void test_wolfSSL_RSA_get0_key(void) RSA_free(rsa); } + printf(resultFmt, passed); +#endif +} + +static void test_wolfSSL_RSA_meth(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + RSA *rsa; + RSA_METHOD *rsa_meth; + + printf(testingFmt, "test_wolfSSL_RSA_meth"); + +#ifdef WOLFSSL_KEY_GEN + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + RSA_free(rsa); +#else + AssertNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); +#endif + + AssertNotNull(rsa_meth = + RSA_meth_new("placeholder RSA method", RSA_METHOD_FLAG_NO_CHECK)); + + AssertIntEQ(RSA_meth_set_pub_enc(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_pub_dec(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_priv_enc(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_priv_dec(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_init(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set_finish(rsa_meth, NULL), 1); + AssertIntEQ(RSA_meth_set0_app_data(rsa_meth, NULL), 1); + + AssertNotNull(rsa = RSA_new()); + AssertIntEQ(RSA_set_method(rsa, rsa_meth), 1); + AssertPtrEq(RSA_get_method(rsa), rsa_meth); + AssertIntEQ(RSA_flags(rsa), RSA_METHOD_FLAG_NO_CHECK); + RSA_set_flags(rsa, RSA_FLAG_CACHE_PUBLIC); + AssertIntEQ(RSA_flags(rsa), RSA_FLAG_CACHE_PUBLIC); + + /* rsa_meth is freed here */ + RSA_free(rsa); printf(resultFmt, passed); #endif @@ -25061,35 +25274,76 @@ static void test_wolfSSL_X509_EXTENSION_get_critical(void) static void test_wolfSSL_X509V3_EXT_print(void) { #if !defined(NO_FILESYSTEM) && defined (OPENSSL_ALL) - FILE* f; - WOLFSSL_X509* x509; - X509_EXTENSION * ext = NULL; - int loc; - BIO *bio = NULL; + printf(testingFmt, "wolfSSL_X509V3_EXT_print"); - AssertNotNull(f = fopen("./certs/server-cert.pem", "rb")); - AssertNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL)); - fclose(f); + { + FILE* f; + WOLFSSL_X509* x509; + X509_EXTENSION * ext = NULL; + int loc; + BIO *bio = NULL; - AssertNotNull(bio = wolfSSL_BIO_new(BIO_s_mem())); + AssertNotNull(f = fopen(svrCertFile, "rb")); + AssertNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL)); + fclose(f); - loc = wolfSSL_X509_get_ext_by_NID(x509, NID_basic_constraints, -1); - AssertIntGT(loc, -1); - AssertNotNull(ext = wolfSSL_X509_get_ext(x509, loc)); - AssertIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS); + AssertNotNull(bio = wolfSSL_BIO_new(BIO_s_mem())); - loc = wolfSSL_X509_get_ext_by_NID(x509, NID_subject_key_identifier, -1); - AssertIntGT(loc, -1); - AssertNotNull(ext = wolfSSL_X509_get_ext(x509, loc)); - AssertIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS); + loc = wolfSSL_X509_get_ext_by_NID(x509, NID_basic_constraints, -1); + AssertIntGT(loc, -1); + AssertNotNull(ext = wolfSSL_X509_get_ext(x509, loc)); + AssertIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS); - loc = wolfSSL_X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1); - AssertIntGT(loc, -1); - AssertNotNull(ext = wolfSSL_X509_get_ext(x509, loc)); - AssertIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS); + loc = wolfSSL_X509_get_ext_by_NID(x509, NID_subject_key_identifier, -1); + AssertIntGT(loc, -1); + AssertNotNull(ext = wolfSSL_X509_get_ext(x509, loc)); + AssertIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS); - wolfSSL_BIO_free(bio); - wolfSSL_X509_free(x509); + loc = wolfSSL_X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1); + AssertIntGT(loc, -1); + AssertNotNull(ext = wolfSSL_X509_get_ext(x509, loc)); + AssertIntEQ(wolfSSL_X509V3_EXT_print(bio, ext, 0, 0), WOLFSSL_SUCCESS); + + wolfSSL_BIO_free(bio); + wolfSSL_X509_free(x509); + } + + { + X509 *x509; + BIO *bio; + X509_EXTENSION *ext; + unsigned int i; + unsigned int idx; + /* Some NIDs to test with */ + int nids[] = { + /* NID_key_usage, currently X509_get_ext returns this as a bit + * string, which messes up X509V3_EXT_print */ + /* NID_ext_key_usage, */ + NID_subject_alt_name, + }; + int* n; + + printf(testingFmt, "wolfSSL_X509V3_EXT_print"); + AssertNotNull(bio = BIO_new_fp(stderr, BIO_NOCLOSE)); + + AssertNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFileExt, + WOLFSSL_FILETYPE_PEM)); + + printf("\nPrinting extension values:\n"); + + for (i = 0, n = nids; i<(sizeof(nids)/sizeof(int)); i++, n++) { + /* X509_get_ext_by_NID should return 3 for now. If that changes then + * update the index */ + AssertIntEQ((idx = X509_get_ext_by_NID(x509, *n, -1)), 3); + AssertNotNull(ext = X509_get_ext(x509, idx)); + AssertIntEQ(X509V3_EXT_print(bio, ext, 0, 0), 1); + printf("\n"); + } + + BIO_free(bio); + X509_free(x509); + } + printf(resultFmt, passed); #endif } @@ -25253,6 +25507,31 @@ static void test_wolfSSL_OCSP_get0_info() #endif /* OPENSSL_EXTRA & HAVE_OCSP */ } +static void test_wolfSSL_EC_get_builtin_curves(void) +{ +#if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) + EC_builtin_curve* curves = NULL; + size_t crv_len = 0; + size_t i = 0; + + printf(testingFmt, "wolfSSL_EC_get_builtin_curves"); + + AssertIntGT((crv_len = EC_get_builtin_curves(NULL, 0)), 0); + AssertNotNull(curves = (EC_builtin_curve*) + XMALLOC(sizeof(EC_builtin_curve)*crv_len, NULL, + DYNAMIC_TYPE_TMP_BUFFER)); + AssertIntEQ(EC_get_builtin_curves(curves, crv_len), crv_len); + + for (i = 0; i < crv_len; i++) + { + AssertStrEQ(OBJ_nid2sn(curves[i].nid), curves[i].comment); + } + + XFREE(curves, NULL, DYNAMIC_TYPE_TMP_BUFFER); + printf(resultFmt, passed); +#endif /* defined(HAVE_ECC) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) */ +} + static void test_no_op_functions(void) { #if defined(OPENSSL_EXTRA) @@ -25881,9 +26160,11 @@ static void test_EVP_PKEY_rsa(void) AssertIntEQ(EVP_PKEY_assign_RSA(NULL, rsa), WOLFSSL_FAILURE); AssertIntEQ(EVP_PKEY_assign_RSA(pkey, NULL), WOLFSSL_FAILURE); AssertIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS); + AssertPtrEq(EVP_PKEY_get0_RSA(pkey), rsa); wolfSSL_EVP_PKEY_free(pkey); printf(resultFmt, passed); + #endif } @@ -27069,6 +27350,7 @@ static void test_wolfSSL_X509_CRL(void) "./certs/crl/eccSrvCRL.pem", "" }; + BIO *bio; #ifdef HAVE_TEST_d2i_X509_CRL_fp char der[][100] = { @@ -27098,6 +27380,14 @@ static void test_wolfSSL_X509_CRL(void) XFCLOSE(fp); } + for (i = 0; pem[i][0] != '\0'; i++) + { + AssertNotNull(bio = BIO_new_file(pem[i], "r")); + AssertNotNull(crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)); + X509_CRL_free(crl); + BIO_free(bio); + } + #ifdef HAVE_TEST_d2i_X509_CRL_fp for(i = 0; der[i][0] != '\0'; i++){ fp = XFOPEN(der[i], "rb"); @@ -27661,6 +27951,23 @@ static void test_wolfSSL_RSA_print() printf(resultFmt, passed); #endif } + +static void test_wolfSSL_BIO_get_len() +{ +#if defined(OPENSSL_EXTRA) + BIO *bio; + const char txt[] = "Some example text to push to the BIO."; + printf(testingFmt, "wolfSSL_BIO_get_len"); + + AssertNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem())); + AssertIntEQ(wolfSSL_BIO_write(bio, txt, sizeof(txt)), sizeof(txt)); + AssertIntEQ(wolfSSL_BIO_get_len(bio), sizeof(txt)); + + BIO_free(bio); + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_ASN1_STRING_print(void){ #if defined(OPENSSL_ALL) && !defined(NO_ASN) && !defined(NO_CERTS) ASN1_STRING* asnStr = NULL; @@ -28310,6 +28617,7 @@ void ApiTest(void) /* X509 tests */ test_wolfSSL_X509_NAME_get_entry(); test_wolfSSL_PKCS12(); + test_wolfSSL_no_password_cb(); test_wolfSSL_PKCS8(); test_wolfSSL_PKCS5(); test_wolfSSL_URI(); @@ -28331,6 +28639,7 @@ void ApiTest(void) /* compatibility tests */ test_wolfSSL_X509_NAME(); + test_wolfSSL_X509_INFO(); test_wolfSSL_X509_subject_name_hash(); test_wolfSSL_DES(); test_wolfSSL_certs(); @@ -28374,6 +28683,7 @@ void ApiTest(void) test_wolfSSL_PEM_read_bio(); test_wolfSSL_BIO(); test_wolfSSL_ASN1_STRING(); + test_wolfSSL_ASN1_BIT_STRING(); test_wolfSSL_X509(); test_wolfSSL_X509_VERIFY_PARAM(); test_wolfSSL_X509_sign(); @@ -28419,6 +28729,7 @@ void ApiTest(void) test_wolfSSL_RSA(); test_wolfSSL_RSA_DER(); test_wolfSSL_RSA_get0_key(); + test_wolfSSL_RSA_meth(); test_wolfSSL_verify_depth(); test_wolfSSL_HMAC_CTX(); test_wolfSSL_msg_callback(); @@ -28456,6 +28767,7 @@ void ApiTest(void) test_wolfSSL_X509_CA_num(); test_wolfSSL_X509_get_version(); test_wolfSSL_X509_print(); + test_wolfSSL_BIO_get_len(); test_wolfSSL_RSA_verify(); test_wolfSSL_X509V3_EXT_get(); test_wolfSSL_X509V3_EXT_d2i(); @@ -28472,6 +28784,8 @@ void ApiTest(void) test_wolfSSL_ASN1_STRING_print(); test_openssl_generate_key_and_cert(); + test_wolfSSL_EC_get_builtin_curves(); + /* test the no op functions for compatibility */ test_no_op_functions(); @@ -28653,6 +28967,7 @@ void ApiTest(void) #ifdef OPENSSL_EXTRA /*wolfSSL_EVP_get_cipherbynid test*/ test_wolfSSL_EVP_get_cipherbynid(); + test_wolfSSL_EVP_CIPHER_CTX(); test_wolfSSL_EC(); test_wolfSSL_ECDSA_SIG(); #endif diff --git a/tests/unit.h b/tests/unit.h index 7efc766a6..e5c26941d 100644 --- a/tests/unit.h +++ b/tests/unit.h @@ -89,6 +89,19 @@ #define AssertStrGE(x, y) AssertStr(x, y, >=, <) #define AssertStrLE(x, y) AssertStr(x, y, <=, >) +#define AssertPtr(x, y, op, er) do { \ + void* _x = (void*)x; \ + void* _y = (void*)y; \ + Assert(_x op _y, ("%s " #op " %s", #x, #y), ("%p " #er " %p", _x, _y)); \ +} while(0) + +#define AssertPtrEq(x, y) AssertPtr(x, y, ==, !=) +#define AssertPtrNE(x, y) AssertInt(x, y, !=, ==) +#define AssertPtrGT(x, y) AssertInt(x, y, >, <=) +#define AssertPtrLT(x, y) AssertInt(x, y, <, >=) +#define AssertPtrGE(x, y) AssertInt(x, y, >=, <) +#define AssertPtrLE(x, y) AssertInt(x, y, <=, >) + void ApiTest(void); int SuiteTest(int argc, char** argv); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 8117d95eb..9ff2ff59d 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -489,6 +489,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) { int fl; + int ret = WOLFSSL_SUCCESS; if (ctx == NULL || out == NULL || outl == NULL) return BAD_FUNC_ARG; @@ -512,48 +513,56 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, if (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) { if (ctx->bufUsed != 0) return WOLFSSL_FAILURE; *outl = 0; - return WOLFSSL_SUCCESS; } - if (ctx->enc) { + else if (ctx->enc) { if (ctx->block_size == 1) { *outl = 0; - return WOLFSSL_SUCCESS; } - if ((ctx->bufUsed >= 0) && (ctx->block_size != 1)) { + else if ((ctx->bufUsed >= 0) && (ctx->block_size != 1)) { padBlock(ctx); PRINT_BUF(ctx->buf, ctx->block_size); - if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) - return WOLFSSL_FAILURE; - - PRINT_BUF(out, ctx->block_size); - *outl = ctx->block_size; + if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) { + ret = WOLFSSL_FAILURE; + } + else { + PRINT_BUF(out, ctx->block_size); + *outl = ctx->block_size; + } } - } else { + } + else { if (ctx->block_size == 1) { *outl = 0; - return WOLFSSL_SUCCESS; } - if ((ctx->bufUsed % ctx->block_size) != 0) { + else if ((ctx->bufUsed % ctx->block_size) != 0) { *outl = 0; /* not enough padding for decrypt */ - return WOLFSSL_FAILURE; + ret = WOLFSSL_FAILURE; } - if (ctx->lastUsed) { + else if (ctx->lastUsed) { PRINT_BUF(ctx->lastBlock, ctx->block_size); if ((fl = checkPad(ctx, ctx->lastBlock)) >= 0) { XMEMCPY(out, ctx->lastBlock, fl); *outl = fl; + if (ctx->lastUsed == 0 && ctx->bufUsed == 0) { + /* return error in cases where the block length is incorrect */ + ret = WOLFSSL_FAILURE; + } } else { - return WOLFSSL_FAILURE; + ret = WOLFSSL_FAILURE; } } - /* return error in cases where the block length is incorrect */ - if (ctx->lastUsed == 0 && ctx->bufUsed == 0) { - return WOLFSSL_FAILURE; + else if (ctx->lastUsed == 0 && ctx->bufUsed == 0) { + /* return error in cases where the block length is incorrect */ + ret = WOLFSSL_FAILURE; } } - return WOLFSSL_SUCCESS; + if (ret == WOLFSSL_SUCCESS) { + /* reset cipher state after final */ + wolfSSL_EVP_CipherInit(ctx, NULL, NULL, NULL, -1); + } + return ret; } @@ -2046,7 +2055,8 @@ int wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, if (pass == NULL) { passlen = 0; pass = nostring; - } else if (passlen == -1) { + } + else if (passlen == -1) { passlen = (int)XSTRLEN(pass); } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ba9e13929..677f9030e 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3455,6 +3455,7 @@ typedef struct Arrays { #define STACK_TYPE_NULL 8 #define STACK_TYPE_X509_NAME 9 #define STACK_TYPE_CONF_VALUE 10 +#define STACK_TYPE_X509_INFO 11 struct WOLFSSL_STACK { unsigned long num; /* number of nodes in stack @@ -3462,6 +3463,7 @@ struct WOLFSSL_STACK { #if defined(OPENSSL_ALL) wolf_sk_compare_cb comp; #endif + union { WOLFSSL_X509* x509; WOLFSSL_X509_NAME* name; @@ -3474,7 +3476,7 @@ struct WOLFSSL_STACK { WOLFSSL_CONF_VALUE* conf; void* generic; char* string; - WOLFSSL_GENERAL_NAME* gn; + WOLFSSL_GENERAL_NAME* gn; } data; void* heap; /* memory heap hint */ WOLFSSL_STACK* next; diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 40719df6d..e5fe8de39 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -68,6 +68,8 @@ #define BIO_gets wolfSSL_BIO_gets #define BIO_puts wolfSSL_BIO_puts +#define BIO_should_retry(...) 1 + #define BIO_TYPE_FILE WOLFSSL_BIO_FILE #define BIO_TYPE_BIO WOLFSSL_BIO_BIO #define BIO_TYPE_MEM WOLFSSL_BIO_MEMORY diff --git a/wolfssl/openssl/buffer.h b/wolfssl/openssl/buffer.h index fce1603e6..4efd31558 100644 --- a/wolfssl/openssl/buffer.h +++ b/wolfssl/openssl/buffer.h @@ -40,10 +40,6 @@ WOLFSSL_API void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf); #define BUF_MEM_grow wolfSSL_BUF_MEM_grow #define BUF_MEM_free wolfSSL_BUF_MEM_free -/* error codes */ -#define ERR_R_MALLOC_FAILURE MEMORY_E - - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 81edb7597..3eb90e416 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -46,8 +46,6 @@ WOLFSSL_API void *wolfSSL_OPENSSL_malloc(size_t a); #define SSLeay_version wolfSSLeay_version #define SSLeay wolfSSLeay -#define OpenSSL_version wolfSSLeay_version - #define SSLEAY_VERSION 0x0090600fL #define SSLEAY_VERSION_NUMBER SSLEAY_VERSION #define CRYPTO_lock wc_LockMutex_ex diff --git a/wolfssl/openssl/des.h b/wolfssl/openssl/des.h index 4ddad98fc..8a356e5e8 100644 --- a/wolfssl/openssl/des.h +++ b/wolfssl/openssl/des.h @@ -84,6 +84,7 @@ WOLFSSL_API void wolfSSL_DES_ncbc_encrypt(const unsigned char* input, WOLFSSL_API void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock*); WOLFSSL_API void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock*, WOLFSSL_DES_cblock*, WOLFSSL_DES_key_schedule*, int); +WOLFSSL_API int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock*); typedef WOLFSSL_DES_cblock DES_cblock; @@ -103,6 +104,7 @@ typedef WOLFSSL_DES_LONG DES_LONG; #define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt #define DES_ede3_cbc_encrypt wolfSSL_DES_ede3_cbc_encrypt #define DES_cbc_cksum wolfSSL_DES_cbc_cksum +#define DES_check_key_parity wolfSSL_DES_check_key_parity #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index baa8f2119..18e3b4e3d 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -102,6 +102,12 @@ struct WOLFSSL_EC_KEY { char exSet; /* external set from internal ? */ }; +typedef struct WOLFSSL_EC_builtin_curve{ + int nid; + const char *comment; +} WOLFSSL_EC_builtin_curve; + +typedef WOLFSSL_EC_builtin_curve EC_builtin_curve; #define WOLFSSL_EC_KEY_LOAD_PRIVATE 1 #define WOLFSSL_EC_KEY_LOAD_PUBLIC 2 @@ -159,6 +165,8 @@ WOLFSSL_API int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group, WOLFSSL_BIGNUM *order, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group); +WOLFSSL_API void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group); WOLFSSL_API WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group); @@ -185,6 +193,9 @@ WOLFSSL_API int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, const WOLFSSL_EC_POINT *a); +WOLFSSL_API +size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_builtin_curve *r, size_t nitems); + #ifndef HAVE_SELFTEST WOLFSSL_API char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, @@ -192,6 +203,10 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, WOLFSSL_BN_CTX* ctx); #endif +#ifndef HAVE_ECC +#define OPENSSL_NO_EC +#endif + #define EC_KEY_new wolfSSL_EC_KEY_new #define EC_KEY_free wolfSSL_EC_KEY_free #define EC_KEY_get0_public_key wolfSSL_EC_KEY_get0_public_key @@ -211,6 +226,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_GROUP_get_curve_name wolfSSL_EC_GROUP_get_curve_name #define EC_GROUP_get_degree wolfSSL_EC_GROUP_get_degree #define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order +#define EC_GROUP_order_bits wolfSSL_EC_GROUP_order_bits #define EC_POINT_new wolfSSL_EC_POINT_new #define EC_POINT_free wolfSSL_EC_POINT_free @@ -226,6 +242,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #endif #define EC_POINT_dump wolfSSL_EC_POINT_dump +#define EC_get_builtin_curves wolfSSL_EC_get_builtin_curves #define EC_curve_nid2nist wolfSSL_EC_curve_nid2nist diff --git a/wolfssl/openssl/err.h b/wolfssl/openssl/err.h index 98a820385..dcfdd1553 100644 --- a/wolfssl/openssl/err.h +++ b/wolfssl/openssl/err.h @@ -28,5 +28,24 @@ #define ERR_load_crypto_strings wolfSSL_ERR_load_crypto_strings #define ERR_peek_last_error wolfSSL_ERR_peek_last_error +/* fatal error */ +#define ERR_R_MALLOC_FAILURE MEMORY_E +#define ERR_R_PASSED_NULL_PARAMETER BAD_FUNC_ARG +#define ERR_R_DISABLED NOT_COMPILED_IN +#define ERR_R_PASSED_INVALID_ARGUMENT BAD_FUNC_ARG +#define RSA_R_UNKNOWN_PADDING_TYPE RSA_PAD_E + +/* SSL function codes */ +#define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT 1 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 2 +#define SSL_F_SSL_USE_PRIVATEKEY 3 + +/* reasons */ +#define ERR_R_SYS_LIB 1 +#define PKCS12_R_MAC_VERIFY_FAILURE 2 + +#define RSAerr(f,r) ERR_put_error(0,(f),(r),__FILE__,__LINE__) +#define SSLerr(f,r) ERR_put_error(0,(f),(r),__FILE__,__LINE__) + #endif /* WOLFSSL_OPENSSL_ERR_ */ diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 07dbf300a..291820664 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -293,6 +293,7 @@ WOLFSSL_API int wolfSSL_EVP_MD_CTX_block_size(const WOLFSSL_EVP_MD_CTX *ctx); WOLFSSL_API const WOLFSSL_EVP_MD *wolfSSL_EVP_MD_CTX_md(const WOLFSSL_EVP_MD_CTX *ctx); WOLFSSL_API const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name); WOLFSSL_API const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name); +WOLFSSL_API int wolfSSL_EVP_CIPHER_nid(const WOLFSSL_EVP_CIPHER *cipher); WOLFSSL_API int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx, const WOLFSSL_EVP_MD* type); @@ -326,7 +327,7 @@ WOLFSSL_API int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, WOLFSSL_API int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen); -WOLFSSL_API int wolfSSL_EVP_Digest(unsigned char* in, int inSz, unsigned char* out, +WOLFSSL_API int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out, unsigned int* outSz, const WOLFSSL_EVP_MD* evp, WOLFSSL_ENGINE* eng); @@ -405,14 +406,17 @@ WOLFSSL_API int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_get_cipherbynid(int); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int); +WOLFSSL_API const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_CIPHER_CTX_cipher(const WOLFSSL_EVP_CIPHER_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_PKEY_assign_RSA(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_RSA* key); WOLFSSL_API int wolfSSL_EVP_PKEY_assign_EC_KEY(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_EC_KEY* key); +WOLFSSL_API WOLFSSL_RSA* wolfSSL_EVP_PKEY_get0_RSA(struct WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY*); WOLFSSL_API WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY*); -WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY *key); +WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get0_EC_KEY(WOLFSSL_EVP_PKEY *pkey); +WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, ENGINE* e, @@ -518,6 +522,7 @@ WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, #define WOLFSSL_EVP_CIPH_GCM_MODE 0x6 #define WOLFSSL_EVP_CIPH_CCM_MODE 0x7 #define WOLFSSL_EVP_CIPH_NO_PADDING 0x100 +#define EVP_CIPH_VARIABLE_LENGTH 0x200 #define WOLFSSL_EVP_CIPH_TYPE_INIT 0xff /* end OpenSSH compat */ @@ -597,6 +602,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_CIPHER_CTX_key_length wolfSSL_EVP_CIPHER_CTX_key_length #define EVP_CIPHER_CTX_set_key_length wolfSSL_EVP_CIPHER_CTX_set_key_length #define EVP_CIPHER_CTX_mode wolfSSL_EVP_CIPHER_CTX_mode +#define EVP_CIPHER_CTX_cipher wolfSSL_EVP_CIPHER_CTX_cipher #define EVP_CIPHER_iv_length wolfSSL_EVP_CIPHER_iv_length #define EVP_CIPHER_key_length wolfSSL_EVP_Cipher_key_length @@ -633,6 +639,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_PKEY_get1_RSA wolfSSL_EVP_PKEY_get1_RSA #define EVP_PKEY_get1_DSA wolfSSL_EVP_PKEY_get1_DSA #define EVP_PKEY_set1_RSA wolfSSL_EVP_PKEY_set1_RSA +#define EVP_PKEY_get0_EC_KEY wolfSSL_EVP_PKEY_get0_EC_KEY #define EVP_PKEY_get1_EC_KEY wolfSSL_EVP_PKEY_get1_EC_KEY #define EVP_PKEY_get0_hmac wolfSSL_EVP_PKEY_get0_hmac #define EVP_PKEY_new_mac_key wolfSSL_EVP_PKEY_new_mac_key @@ -688,6 +695,8 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define OpenSSL_add_all_algorithms_noconf wolfSSL_OpenSSL_add_all_algorithms_noconf #define wolfSSL_OPENSSL_add_all_algorithms_noconf wolfSSL_OpenSSL_add_all_algorithms_noconf +#define NO_PADDING_BLOCK_SIZE 1 + #define PKCS5_PBKDF2_HMAC_SHA1 wolfSSL_PKCS5_PBKDF2_HMAC_SHA1 #define PKCS5_PBKDF2_HMAC wolfSSL_PKCS5_PBKDF2_HMAC @@ -708,6 +717,14 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_MAX_MD_SIZE 64 /* sha512 */ #endif +#ifndef EVP_MAX_KEY_LENGTH +#define EVP_MAX_KEY_LENGTH 64 +#endif + +#ifndef EVP_MAX_IV_LENGTH +#define EVP_MAX_IV_LENGTH 16 +#endif + #ifndef EVP_MAX_BLOCK_LENGTH #define EVP_MAX_BLOCK_LENGTH 32 /* 2 * blocklen(AES)? */ /* They define this as 32. Using the same value here. */ diff --git a/wolfssl/openssl/hmac.h b/wolfssl/openssl/hmac.h index fe034654e..7a906170a 100644 --- a/wolfssl/openssl/hmac.h +++ b/wolfssl/openssl/hmac.h @@ -58,6 +58,7 @@ typedef struct WOLFSSL_HMAC_CTX { } WOLFSSL_HMAC_CTX; +WOLFSSL_API WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void); WOLFSSL_API int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx); WOLFSSL_API int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src); @@ -71,18 +72,24 @@ WOLFSSL_API int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, WOLFSSL_API int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash, unsigned int* len); WOLFSSL_API int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx); +WOLFSSL_API void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx); +WOLFSSL_API size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx); typedef struct WOLFSSL_HMAC_CTX HMAC_CTX; #define HMAC(a,b,c,d,e,f,g) wolfSSL_HMAC((a),(b),(c),(d),(e),(f),(g)) +#define HMAC_CTX_new wolfSSL_HMAC_CTX_new #define HMAC_CTX_init wolfSSL_HMAC_CTX_Init #define HMAC_CTX_copy wolfSSL_HMAC_CTX_copy +#define HMAC_CTX_free wolfSSL_HMAC_CTX_free +#define HMAC_CTX_reset wolfSSL_HMAC_cleanup #define HMAC_Init_ex wolfSSL_HMAC_Init_ex #define HMAC_Init wolfSSL_HMAC_Init #define HMAC_Update wolfSSL_HMAC_Update #define HMAC_Final wolfSSL_HMAC_Final #define HMAC_cleanup wolfSSL_HMAC_cleanup +#define HMAC_size wolfSSL_HMAC_size #ifdef __cplusplus diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index 775e60dc5..f7ce8b754 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -39,6 +39,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/ssl23.h \ wolfssl/openssl/ssl.h \ wolfssl/openssl/stack.h \ + wolfssl/openssl/tls1.h \ wolfssl/openssl/ui.h \ wolfssl/openssl/x509.h \ wolfssl/openssl/x509_vfy.h \ diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index d1a4bed3c..6d956f402 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -27,7 +27,6 @@ #include - #ifdef __cplusplus extern "C" { #endif @@ -38,6 +37,16 @@ #define RSA_PKCS1_PSS_PADDING 2 #define RSA_NO_PADDING 3 +/* Emulate OpenSSL flags */ +#define RSA_METHOD_FLAG_NO_CHECK (1 << 1) +#define RSA_FLAG_CACHE_PUBLIC (1 << 2) +#define RSA_FLAG_CACHE_PRIVATE (1 << 3) +#define RSA_FLAG_BLINDING (1 << 4) +#define RSA_FLAG_THREAD_SAFE (1 << 5) +#define RSA_FLAG_EXT_PKEY (1 << 6) +#define RSA_FLAG_NO_BLINDING (1 << 7) +#define RSA_FLAG_NO_CONSTTIME (1 << 8) + #ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */ typedef struct WOLFSSL_RSA WOLFSSL_RSA; #define WOLFSSL_RSA_TYPE_DEFINED @@ -45,6 +54,13 @@ typedef struct WOLFSSL_RSA WOLFSSL_RSA; typedef WOLFSSL_RSA RSA; +typedef struct WOLFSSL_RSA_METHOD { + int flags; + char *name; +} WOLFSSL_RSA_METHOD; + +typedef WOLFSSL_RSA_METHOD RSA_METHOD; + struct WOLFSSL_RSA { #ifdef WC_RSA_BLINDING WC_RNG* rng; /* for PrivateDecrypt blinding */ @@ -62,9 +78,11 @@ struct WOLFSSL_RSA { char inSet; /* internal set from external ? */ char exSet; /* external set from internal ? */ char ownRng; /* flag for if the rng should be free'd */ +#if defined(OPENSSL_EXTRA) + WOLFSSL_RSA_METHOD* meth; +#endif }; - WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void); WOLFSSL_API void wolfSSL_RSA_free(WOLFSSL_RSA*); @@ -95,8 +113,17 @@ WOLFSSL_API int wolfSSL_RSA_GenAdd(WOLFSSL_RSA*); WOLFSSL_API int wolfSSL_RSA_LoadDer(WOLFSSL_RSA*, const unsigned char*, int sz); WOLFSSL_API int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA*, const unsigned char*, int sz, int opt); -WOLFSSL_API void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, - const WOLFSSL_BIGNUM **n, const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d); +WOLFSSL_API WOLFSSL_RSA_METHOD *wolfSSL_RSA_meth_new(const char *name, int flags); +WOLFSSL_API void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth); +WOLFSSL_API int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *rsa, void* p); +WOLFSSL_API int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth); +WOLFSSL_API const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa); +WOLFSSL_API void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, + const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d); +WOLFSSL_API int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, + WOLFSSL_BIGNUM *d); +WOLFSSL_API int wolfSSL_RSA_flags(const WOLFSSL_RSA *r); +WOLFSSL_API void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags); #define WOLFSSL_RSA_LOAD_PRIVATE 1 #define WOLFSSL_RSA_LOAD_PUBLIC 2 @@ -116,6 +143,23 @@ WOLFSSL_API void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, #define RSA_sign wolfSSL_RSA_sign #define RSA_verify wolfSSL_RSA_verify #define RSA_public_decrypt wolfSSL_RSA_public_decrypt +#define EVP_PKEY_get0_RSA wolfSSL_EVP_PKEY_get0_RSA + +#define RSA_meth_new wolfSSL_RSA_meth_new +#define RSA_meth_free wolfSSL_RSA_meth_free +#define RSA_meth_set_pub_enc wolfSSL_RSA_meth_set +#define RSA_meth_set_pub_dec wolfSSL_RSA_meth_set +#define RSA_meth_set_priv_enc wolfSSL_RSA_meth_set +#define RSA_meth_set_priv_dec wolfSSL_RSA_meth_set +#define RSA_meth_set_init wolfSSL_RSA_meth_set +#define RSA_meth_set_finish wolfSSL_RSA_meth_set +#define RSA_meth_set0_app_data wolfSSL_RSA_meth_set +#define RSA_get_method wolfSSL_RSA_get_method +#define RSA_set_method wolfSSL_RSA_set_method +#define RSA_get0_key wolfSSL_RSA_get0_key +#define RSA_set0_key wolfSSL_RSA_set0_key +#define RSA_flags wolfSSL_RSA_flags +#define RSA_set_flags wolfSSL_RSA_set_flags #define RSA_get0_key wolfSSL_RSA_get0_key diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index f80fa6674..c0a99dbb2 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -35,7 +35,9 @@ #include #endif /* OPENSSL_EXTRA_SSL_GUARD */ +#include #include +#include #ifdef OPENSSL_EXTRA #include #endif @@ -89,6 +91,7 @@ typedef WOLFSSL_ASN1_INTEGER ASN1_INTEGER; typedef WOLFSSL_ASN1_OBJECT ASN1_OBJECT; typedef WOLFSSL_ASN1_STRING ASN1_STRING; typedef WOLFSSL_ASN1_TYPE ASN1_TYPE; +typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; typedef WOLFSSL_dynlock_value CRYPTO_dynlock_value; typedef WOLFSSL_BUF_MEM BUF_MEM; typedef WOLFSSL_GENERAL_NAMES GENERAL_NAMES; @@ -249,7 +252,12 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define SSL_library_init wolfSSL_library_init #define SSL_CTX_set_session_cache_mode wolfSSL_CTX_set_session_cache_mode #define SSL_CTX_set_cipher_list wolfSSL_CTX_set_cipher_list +#define SSL_CTX_set_ciphersuites wolfSSL_CTX_set_cipher_list #define SSL_set_cipher_list wolfSSL_set_cipher_list +/* wolfSSL does not support security levels */ +#define SSL_CTX_set_security_level(...) +/* wolfSSL does not support expoting keying material */ +#define SSL_export_keying_material(...) 0 #define SSL_set_ex_data wolfSSL_set_ex_data #define SSL_get_shutdown wolfSSL_get_shutdown @@ -294,6 +302,9 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #endif #define DSA_dup_DH wolfSSL_DSA_dup_DH +/* wolfSSL does not support DSA as the cert public key */ +#define EVP_PKEY_get0_DSA(...) NULL +#define DSA_bits(...) 0 #define i2d_X509_bio wolfSSL_i2d_X509_bio #define d2i_X509_bio wolfSSL_d2i_X509_bio @@ -301,11 +312,13 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define i2d_X509 wolfSSL_i2d_X509 #define d2i_X509 wolfSSL_d2i_X509 #define PEM_read_bio_X509 wolfSSL_PEM_read_bio_X509 +#define PEM_read_bio_X509_CRL wolfSSL_PEM_read_bio_X509_CRL #define PEM_read_bio_X509_AUX wolfSSL_PEM_read_bio_X509_AUX #define PEM_read_X509 wolfSSL_PEM_read_X509 #define PEM_X509_INFO_read_bio wolfSSL_PEM_X509_INFO_read_bio #define PEM_write_bio_X509 wolfSSL_PEM_write_bio_X509 #define PEM_write_bio_X509_AUX wolfSSL_PEM_write_bio_X509_AUX +#define PEM_X509_INFO_read_bio wolfSSL_PEM_X509_INFO_read_bio #define i2d_PrivateKey wolfSSL_i2d_PrivateKey #define i2d_X509_REQ wolfSSL_i2d_X509_REQ @@ -324,13 +337,12 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define X509_digest wolfSSL_X509_digest #define X509_get_ext_count wolfSSL_X509_get_ext_count #define X509_get_ext_d2i wolfSSL_X509_get_ext_d2i -#define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID #define X509_get_ext wolfSSL_X509_get_ext #define X509_get_ext_by_NID wolfSSL_X509_get_ext_by_NID -#define X509_add_ext wolfSSL_X509_add_ext #define X509_get_issuer_name wolfSSL_X509_get_issuer_name #define X509_get_subject_name wolfSSL_X509_get_subject_name #define X509_get_pubkey wolfSSL_X509_get_pubkey +#define X509_get0_pubkey wolfSSL_X509_get_pubkey #define X509_get_notBefore wolfSSL_X509_get_notBefore #define X509_get_notAfter wolfSSL_X509_get_notAfter #define X509_get_serialNumber wolfSSL_X509_get_serialNumber @@ -399,6 +411,7 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define X509_NAME_free wolfSSL_X509_NAME_free #define X509_NAME_dup wolfSSL_X509_NAME_dup #define X509_NAME_get_text_by_NID wolfSSL_X509_NAME_get_text_by_NID +#define X509_NAME_get_index_by_OBJ wolfSSL_X509_NAME_get_index_by_OBJ #define X509_NAME_cmp wolfSSL_X509_NAME_cmp #define X509_NAME_ENTRY_free wolfSSL_X509_NAME_ENTRY_free #define X509_NAME_ENTRY_create_by_NID wolfSSL_X509_NAME_ENTRY_create_by_NID @@ -501,6 +514,8 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define X509_OBJECT_free_contents wolfSSL_X509_OBJECT_free_contents #define X509_subject_name_hash wolfSSL_X509_subject_name_hash +#define X509_check_purpose(...) 0 + #define OCSP_parse_url wolfSSL_OCSP_parse_url #define MD4_Init wolfSSL_MD4_Init @@ -530,6 +545,7 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define BIO_f_ssl wolfSSL_BIO_f_ssl #define BIO_new_socket wolfSSL_BIO_new_socket #define SSL_set_bio wolfSSL_set_bio +#define BIO_set_ssl wolfSSL_BIO_set_ssl #define BIO_eof wolfSSL_BIO_eof #define BIO_set_ss wolfSSL_BIO_set_ss @@ -560,8 +576,12 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define SSL_get_ex_new_index wolfSSL_get_ex_new_index +#define ASN1_BIT_STRING_new wolfSSL_ASN1_BIT_STRING_new +#define ASN1_BIT_STRING_free wolfSSL_ASN1_BIT_STRING_free +#define ASN1_BIT_STRING_get_bit wolfSSL_ASN1_BIT_STRING_get_bit +#define ASN1_BIT_STRING_set_bit wolfSSL_ASN1_BIT_STRING_set_bit -typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; +#define sk_ASN1_OBJECT_free wolfSSL_sk_ASN1_OBJECT_free #define ASN1_TIME_adj wolfSSL_ASN1_TIME_adj #define ASN1_TIME_print wolfSSL_ASN1_TIME_print @@ -599,7 +619,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define SSL_load_client_CA_file wolfSSL_load_client_CA_file -#define SSL_CTX_get_client_CA_list wolfSSL_SSL_CTX_get_client_CA_list +#define SSL_CTX_get_client_CA_list wolfSSL_CTX_get_client_CA_list #define SSL_CTX_set_client_CA_list wolfSSL_CTX_set_client_CA_list #define SSL_CTX_set_client_cert_cb wolfSSL_CTX_set_client_cert_cb #define SSL_CTX_set_cert_store wolfSSL_CTX_set_cert_store @@ -624,6 +644,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define RSA_generate_key wolfSSL_RSA_generate_key #define SSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback #define RSA_print wolfSSL_RSA_print +#define RSA_bits wolfSSL_RSA_size #define PEM_def_callback wolfSSL_PEM_def_callback @@ -725,7 +746,9 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define BIO_prf wolfSSL_BIO_prf #define sk_num wolfSSL_sk_num +#define sk_ASN1_OBJECT_num wolfSSL_sk_num #define sk_value wolfSSL_sk_value +#define sk_ASN1_OBJECT_value wolfSSL_sk_value #define d2i_PKCS12_bio wolfSSL_d2i_PKCS12_bio #define d2i_PKCS12_fp wolfSSL_d2i_PKCS12_fp @@ -790,6 +813,8 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define SSL_dup_CA_list wolfSSL_dup_CA_list +#define sk_X509_NAME_find wolfSSL_sk_X509_NAME_find + enum { GEN_DNS = 0x02, /* ASN_DNS_TYPE */ GEN_EMAIL = 0x01, /* ASN_RFC822_TYPE */ @@ -958,11 +983,14 @@ enum { #define SSL_SESSION_get_id wolfSSL_SESSION_get_id #define SSL_SESSION_print wolfSSL_SESSION_print #define sk_GENERAL_NAME_pop_free wolfSSL_sk_GENERAL_NAME_pop_free +#define sk_GENERAL_NAME_free wolfSSL_sk_GENERAL_NAME_free +#define sk_ASN1_OBJECT_pop_free wolfSSL_sk_ASN1_OBJECT_pop_free #define GENERAL_NAME_free wolfSSL_GENERAL_NAME_free #define GENERAL_NAMES_free wolfSSL_GENERAL_NAMES_free #define AUTHORITY_INFO_ACCESS_free wolfSSL_AUTHORITY_INFO_ACCESS_free #define sk_ACCESS_DESCRIPTION_pop_free wolfSSL_sk_ACCESS_DESCRIPTION_pop_free +#define sk_ACCESS_DESCRIPTION_free wolfSSL_sk_ACCESS_DESCRIPTION_free #define ACCESS_DESCRIPTION_free NULL #define SSL3_AL_FATAL 2 @@ -1110,6 +1138,22 @@ enum { #define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) #define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) +#define EVP_CIPHER_mode WOLFSSL_CIPHER_mode +/* WOLFSSL_EVP_CIPHER is just the string name of the cipher */ +#define EVP_CIPHER_name(x) x +#define EVP_MD_CTX_reset wolfSSL_EVP_MD_CTX_cleanup +/* WOLFSSL_EVP_MD is just the string name of the digest */ +#define EVP_MD_name(x) x +#define X509_STORE_get0_objects wolfSSL_X509_STORE_get0_objects +#define sk_X509_OBJECT_num wolfSSL_sk_X509_OBJECT_num +#define sk_X509_OBJECT_value wolfSSL_sk_X509_OBJECT_value +#define sk_X509_OBJECT_delete wolfSSL_sk_X509_OBJECT_delete +#define X509_OBJECT_free wolfSSL_X509_OBJECT_free +#define X509_OBJECT_get_type(x) 0 +#define EVP_CIPHER_nid wolfSSL_EVP_CIPHER_nid + +#define OpenSSL_version(x) wolfSSL_lib_version() + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/openssl/stack.h b/wolfssl/openssl/stack.h index 394047050..84bcbae88 100644 --- a/wolfssl/openssl/stack.h +++ b/wolfssl/openssl/stack.h @@ -30,19 +30,15 @@ typedef void (*wolfSSL_sk_freefunc)(void *); -WOLFSSL_API void wolfSSL_sk_free(WOLFSSL_STACK *); +WOLFSSL_API void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, wolfSSL_sk_freefunc); WOLFSSL_API void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK *); WOLFSSL_API int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK *sk, void *data); WOLFSSL_API void wolfSSL_sk_pop_free(WOLFSSL_STACK *st, void (*func) (void *)); -WOLFSSL_API -void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk); +WOLFSSL_API void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk); WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_new_null(void); -WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); -WOLFSSL_API -int wolfSSL_sk_CIPHER_push(WOLFSSL_STACK *st,WOLFSSL_CIPHER *cipher); -WOLFSSL_API -WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); +WOLFSSL_API int wolfSSL_sk_CIPHER_push(WOLFSSL_STACK *st,WOLFSSL_CIPHER *cipher); +WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_cipher(void); #define OPENSSL_sk_free wolfSSL_sk_free diff --git a/wolfssl/openssl/tls1.h b/wolfssl/openssl/tls1.h new file mode 100644 index 000000000..074c85416 --- /dev/null +++ b/wolfssl/openssl/tls1.h @@ -0,0 +1,46 @@ +/* tls1.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef WOLFSSL_OPENSSL_TLS1_H_ +#define WOLFSSL_OPENSSL_TLS1_H_ + +#ifndef TLS1_VERSION +#define TLS1_VERSION 0x0301 +#endif + +#ifndef TLS1_1_VERSION +#define TLS1_1_VERSION 0x0302 +#endif + +#ifndef TLS1_2_VERSION +#define TLS1_2_VERSION 0x0303 +#endif + +#ifndef TLS1_3_VERSION +#define TLS1_3_VERSION 0x0304 +#endif + +#ifndef TLS_MAX_VERSION +#define TLS_MAX_VERSION TLS1_3_VERSION +#endif + +#endif /* WOLFSSL_OPENSSL_TLS1_H_ */ diff --git a/wolfssl/openssl/x509.h b/wolfssl/openssl/x509.h index 72329d91f..55fe71be5 100644 --- a/wolfssl/openssl/x509.h +++ b/wolfssl/openssl/x509.h @@ -18,3 +18,6 @@ #define X509_FLAG_NO_AUX (1UL << 10) #define X509_FLAG_NO_ATTRIBUTES (1UL << 11) #define X509_FLAG_NO_IDS (1UL << 12) + +#define XN_FLAG_FN_SN 0 +#define XN_FLAG_SEP_CPLUS_SPC 2 diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index ba3a67f02..e28783465 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -31,8 +31,13 @@ extern "C" { #endif +#define X509_PURPOSE_SSL_CLIENT 0 +#define X509_PURPOSE_SSL_SERVER 1 + +#define NS_SSL_CLIENT 0 +#define NS_SSL_SERVER 1 + /* Forward reference */ -typedef struct WOLFSSL_v3_ext_method WOLFSSL_v3_ext_method; typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V) ( @@ -53,6 +58,14 @@ struct WOLFSSL_v3_ext_method { X509V3_EXT_I2R i2r; }; +struct WOLFSSL_X509_EXTENSION { + WOLFSSL_ASN1_OBJECT *obj; + WOLFSSL_ASN1_BOOLEAN crit; + WOLFSSL_ASN1_STRING value; + WOLFSSL_v3_ext_method ext_method; + WOLFSSL_STACK* ext_sk; /* For extension specific data */ +}; + #define WOLFSSL_ASN1_BOOLEAN int #define GEN_OTHERNAME 0 #define GEN_EMAIL 1 @@ -68,14 +81,6 @@ struct WOLFSSL_v3_ext_method { #define X509V3_CTX WOLFSSL_X509V3_CTX -struct WOLFSSL_X509_EXTENSION { - WOLFSSL_ASN1_OBJECT *obj; - WOLFSSL_ASN1_BOOLEAN crit; - WOLFSSL_ASN1_STRING value; - WOLFSSL_v3_ext_method ext_method; - WOLFSSL_STACK* ext_sk; /* For extension specific data */ -}; - typedef struct WOLFSSL_AUTHORITY_KEYID AUTHORITY_KEYID; typedef struct WOLFSSL_BASIC_CONSTRAINTS BASIC_CONSTRAINTS; typedef struct WOLFSSL_ACCESS_DESCRIPTION ACCESS_DESCRIPTION; @@ -98,7 +103,6 @@ WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, #define ASN1_OCTET_STRING WOLFSSL_ASN1_STRING #define X509V3_EXT_get wolfSSL_X509V3_EXT_get #define X509V3_EXT_d2i wolfSSL_X509V3_EXT_d2i -#define X509V3_EXT_print wolfSSL_X509V3_EXT_print #define i2s_ASN1_OCTET_STRING wolfSSL_i2s_ASN1_STRING #define X509V3_EXT_print wolfSSL_X509V3_EXT_print #define X509V3_EXT_conf_nid wolfSSL_X509V3_EXT_conf_nid diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index bc162965f..47dff9349 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -126,6 +126,7 @@ typedef struct WOLFSSL_X509_PUBKEY WOLFSSL_X509_PUBKEY; typedef struct WOLFSSL_X509_ALGOR WOLFSSL_X509_ALGOR; typedef struct WOLFSSL_X509_CHAIN WOLFSSL_X509_CHAIN; typedef struct WC_PKCS12 WOLFSSL_X509_PKCS12; +typedef struct WOLFSSL_X509_INFO WOLFSSL_X509_INFO; typedef struct WOLFSSL_CERT_MANAGER WOLFSSL_CERT_MANAGER; typedef struct WOLFSSL_SOCKADDR WOLFSSL_SOCKADDR; @@ -180,6 +181,7 @@ typedef struct WOLFSSL_ASN1_TIME WOLFSSL_ASN1_TIME; typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; typedef struct WOLFSSL_ASN1_OTHERNAME WOLFSSL_ASN1_OTHERNAME; typedef struct WOLFSSL_X509V3_CTX WOLFSSL_X509V3_CTX; +typedef struct WOLFSSL_v3_ext_method WOLFSSL_v3_ext_method; typedef struct WOLFSSL_ASN1_STRING WOLFSSL_ASN1_STRING; typedef struct WOLFSSL_dynlock_value WOLFSSL_dynlock_value; @@ -282,7 +284,7 @@ struct WOLFSSL_ASN1_OBJECT { int grp; /* type of OID, i.e. oidCertPolicyType */ int nid; unsigned int objSz; -#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || defined(WOLFSSL_APACHE_HTTPD) int ca; WOLFSSL_ASN1_INTEGER *pathlen; #endif @@ -374,7 +376,6 @@ struct WOLFSSL_X509_INFO { char *enc_data; int num; }; -typedef struct WOLFSSL_X509_INFO WOLFSSL_X509_INFO; #define WOLFSSL_EVP_PKEY_DEFAULT EVP_PKEY_RSA /* default key type */ @@ -1020,8 +1021,11 @@ typedef int WOLFSSL_LHASH; #endif WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap); +WOLFSSL_API void wolfSSL_sk_free(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_sk_free_node(WOLFSSL_STACK* in); WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx); +WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); #if defined(HAVE_OCSP) #include "wolfssl/ocsp.h" @@ -1049,15 +1053,17 @@ WOLFSSL_API WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value( WOLFSSL_STACK* sk, int i); WOLFSSL_API int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk, - void f (WOLFSSL_GENERAL_NAME*)); + void (*f) (WOLFSSL_GENERAL_NAME*)); +WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES* name); WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_AUTHORITY_INFO_ACCESS_free( WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk); WOLFSSL_API WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value( WOLFSSL_STACK* sk, int idx); +WOLFSSL_API void wolfSSL_sk_ACCESS_DESCRIPTION_free(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk, - void f (WOLFSSL_ACCESS_DESCRIPTION*)); + void (*f) (WOLFSSL_ACCESS_DESCRIPTION*)); WOLFSSL_API void wolfSSL_sk_X509_EXTENSION_pop_free( WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, void f (WOLFSSL_X509_EXTENSION*)); @@ -1072,7 +1078,7 @@ WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop( WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk); WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_pop_free( WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, - void (*func)(WOLFSSL_ASN1_OBJECT*)); + void (*f)(WOLFSSL_ASN1_OBJECT*)); WOLFSSL_API int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in); WOLFSSL_API int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value( @@ -1197,6 +1203,7 @@ WOLFSSL_API int wolfSSL_BIO_seek(WOLFSSL_BIO *bio, int ofs); WOLFSSL_API int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name); WOLFSSL_API long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v); WOLFSSL_API long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **m); +WOLFSSL_API int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio); WOLFSSL_API void wolfSSL_RAND_screen(void); WOLFSSL_API const char* wolfSSL_RAND_file_name(char*, unsigned long); @@ -1263,8 +1270,8 @@ WOLFSSL_API int wolfSSL_X509_set_notAfter(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t); WOLFSSL_API int wolfSSL_X509_set_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME* t); -WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(WOLFSSL_X509* x509); -WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(WOLFSSL_X509* x509); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509* x509); +WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x509); WOLFSSL_API int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s); WOLFSSL_API int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v); @@ -1389,8 +1396,11 @@ WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME*, time_t, #endif WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char*); -WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_SSL_CTX_get_client_CA_list( +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list( const WOLFSSL_CTX *s); +/* depricated function name */ +#define wolfSSL_SSL_CTX_get_client_CA_list wolfSSL_CTX_get_client_CA_list + WOLFSSL_API void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX*, WOLF_STACK_OF(WOLFSSL_X509_NAME)*); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list( @@ -3039,6 +3049,11 @@ struct WOLFSSL_X509_NAME_ENTRY { int set; int size; }; + +WOLFSSL_API int wolfSSL_X509_NAME_get_index_by_OBJ(WOLFSSL_X509_NAME *name, + const WOLFSSL_ASN1_OBJECT *obj, + int idx); + #endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -3064,7 +3079,7 @@ enum { }; /* Object functions */ -WOLFSSL_API const char * wolfSSL_OBJ_nid2sn(int n); +WOLFSSL_API const char* wolfSSL_OBJ_nid2sn(int n); WOLFSSL_API int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o); WOLFSSL_API int wolfSSL_OBJ_sn2nid(const char *sn); @@ -3102,7 +3117,8 @@ WOLFSSL_API int wolfSSL_X509_NAME_add_entry_by_NID(WOLFSSL_X509_NAME *name, int WOLFSSL_API int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x, const WOLFSSL_X509_NAME* y); WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void); -WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME* name); +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509*); +WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME*); WOLFSSL_API int wolfSSL_check_private_key(const WOLFSSL* ssl); WOLFSSL_API void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, int* idx); @@ -3178,6 +3194,8 @@ WOLFSSL_API size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, size_t outSz); WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_bio_X509_CRL(WOLFSSL_BIO *bp, + WOLFSSL_X509_CRL **x, pem_password_cb *cb, void *u); WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX (WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio( @@ -3232,6 +3250,7 @@ WOLFSSL_API int wolfSSL_X509_check_ca(WOLFSSL_X509 *x509); #ifndef NO_FILESYSTEM WOLFSSL_API long wolfSSL_BIO_set_fp(WOLFSSL_BIO *bio, XFILE fp, int c); WOLFSSL_API long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_fp(XFILE fp, int c); #endif #endif /* OPENSSL_EXTRA || OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ @@ -3247,9 +3266,6 @@ WOLFSSL_API long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp); || defined(OPENSSL_EXTRA) WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_file(const char *filename, const char *mode); -#ifndef NO_FILESYSTEM -WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_fp(XFILE fp, int close_flag); -#endif WOLFSSL_API long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX*, WOLFSSL_DH*); WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x, pem_password_cb *cb, void *u); @@ -3334,7 +3350,7 @@ WOLFSSL_API int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)*, WOLFSSL_X509_INFO*); WOLFSSL_API WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(WOLF_STACK_OF(WOLFSSL_X509_INFO)*); WOLFSSL_API void wolfSSL_sk_X509_INFO_pop_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)*, - void f (WOLFSSL_X509_INFO*)); + void (*f) (WOLFSSL_X509_INFO*)); WOLFSSL_API void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO)*); typedef int (*wolf_sk_compare_cb)(const void* const *a, @@ -3351,14 +3367,22 @@ WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value(const WOLF_STACK_OF(WO WOLFSSL_API int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME)*); WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)*); WOLFSSL_API void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)*, - void f (WOLFSSL_X509_NAME*)); + void (*f) (WOLFSSL_X509_NAME*)); WOLFSSL_API void wolfSSL_sk_X509_NAME_free(WOLF_STACK_OF(WOLFSSL_X509_NAME) *); +WOLFSSL_API int wolfSSL_sk_X509_OBJECT_num(const WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *s); + WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO*,WOLFSSL_X509_NAME*,int, unsigned long); +WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void); +WOLFSSL_API void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING*); WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr( const WOLFSSL_X509*); +WOLFSSL_API int wolfSSL_ASN1_BIT_STRING_get_bit( + const WOLFSSL_ASN1_BIT_STRING*, int); +WOLFSSL_API int wolfSSL_ASN1_BIT_STRING_set_bit( + WOLFSSL_ASN1_BIT_STRING*, int, int); WOLFSSL_API int wolfSSL_CTX_add_session(WOLFSSL_CTX*, WOLFSSL_SESSION*); @@ -3366,9 +3390,11 @@ WOLFSSL_API int wolfSSL_version(WOLFSSL*); WOLFSSL_API int wolfSSL_get_state(const WOLFSSL*); -WOLFSSL_API void* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)*, int); +WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)*, int); -WOLFSSL_API void* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)*); +WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)*); + +WOLFSSL_API void* wolfSSL_sk_X509_OBJECT_value(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)*, int); WOLFSSL_API void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION*, int); @@ -3417,8 +3443,13 @@ WOLFSSL_API void wolfSSL_THREADID_set_numeric(void* id, unsigned long val); WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( WOLFSSL_X509_STORE_CTX*, WOLFSSL_X509_NAME*); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* + wolfSSL_X509_STORE_get0_objects(WOLFSSL_X509_STORE *); +WOLFSSL_API WOLFSSL_X509_OBJECT* + wolfSSL_sk_X509_OBJECT_delete(WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, int i); +WOLFSSL_API void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *a); -WOLFSSL_API void wolfSSL_sk_X509_pop_free(WOLF_STACK_OF(WOLFSSL_X509)* sk, void f (WOLFSSL_X509*)); +WOLFSSL_API void wolfSSL_sk_X509_pop_free(WOLF_STACK_OF(WOLFSSL_X509)* sk, void (*f) (WOLFSSL_X509*)); #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_LIGHTY */ #if defined(OPENSSL_ALL) || \ @@ -3533,8 +3564,6 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 * WOLFSSL_API int wolfSSL_X509_check_issued(WOLFSSL_X509 *issuer, WOLFSSL_X509 *subject); -WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509 *x); - WOLFSSL_API char* wolfSSL_sk_WOLFSSL_STRING_value( WOLF_STACK_OF(WOLFSSL_STRING)* strings, int idx); #endif /* HAVE_OCSP */ diff --git a/wolfssl/test.h b/wolfssl/test.h index 69b7bddd8..fc1eb0807 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -298,6 +298,8 @@ #define svrKeyFile "certs/server-key.pem" #define cliCertFile "certs/client-cert.pem" #define cliCertDerFile "certs/client-cert.der" +#define cliCertFileExt "certs/client-cert-ext.pem" +#define cliCertDerFileExt "certs/client-cert-ext.der" #define cliKeyFile "certs/client-key.pem" #define ntruCertFile "certs/ntru-cert.pem" #define ntruKeyFile "certs/ntru-key.raw" @@ -324,6 +326,8 @@ #define svrKeyFile "./certs/server-key.pem" #define cliCertFile "./certs/client-cert.pem" #define cliCertDerFile "./certs/client-cert.der" +#define cliCertFileExt "./certs/client-cert-ext.pem" +#define cliCertDerFileExt "./certs/client-cert-ext.der" #define cliKeyFile "./certs/client-key.pem" #define ntruCertFile "./certs/ntru-cert.pem" #define ntruKeyFile "./certs/ntru-key.raw" diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 1edb0f63f..e79d87411 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -112,6 +112,7 @@ enum ASN_Tags { #define ASN_GENERALIZED_TIME_MAX 68 enum DN_Tags { + ASN_DN_NULL = 0x00, ASN_COMMON_NAME = 0x03, /* CN */ ASN_SUR_NAME = 0x04, /* SN */ ASN_SERIAL_NUMBER = 0x05, /* serialNumber */ @@ -164,6 +165,7 @@ enum DN_Tags { enum { NID_undef = 0, + NID_netscape_cert_type = NID_undef, NID_des = 66, NID_des3 = 67, NID_sha256 = 672, @@ -617,7 +619,7 @@ struct DecodedName { int dcLen[DOMAIN_COMPONENT_MAX]; int dcNum; int dcMode; -#ifdef OPENSSL_EXTRA +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) /* hold the location / order with which each of the DN tags was found * * example of ASN_DOMAIN_COMPONENT at index 0 if first found and so on.