Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions certs/test/alt-chain-forged-ca/gen-alt-chain-forged-ca.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
#
# gen-alt-chain-forged-ca.sh
# Generate the forged-CA alternate chain test certs.
#
# realRoot trusted anchor, CN=Root, fixed SKID DEADBEEF...
# evilRoot attacker key with the same name and SKID as realRoot. Only
# used to sign attackerCA; never sent or trusted.
# attackerCA CA issued by evilRoot. Its issuer name and AKID point at
# realRoot, so the peer finds realRoot as signer but the
# signature does not verify.
# intermediate unrelated self-signed CA, gives ASN_SELF_SIGNED_E which the
# alternate cert chain code bypasses.
# leaf issued by attackerCA.
#
# server-chain.pem is sent as: leaf, intermediate, attackerCA. Only it,
# realRoot-cert.pem and leaf-key.pem (the server's key) are kept. All other
# keys and certs are made fresh in a temp dir and removed once the chain is
# made.

set -e

DIR="$(cd "$(dirname "$0")" && pwd)"
WORK="$(mktemp -d)"
trap 'rm -f "$WORK"/*; rmdir "$WORK"' EXIT

cat > "$WORK/ext.cnf" <<'CNF'
[req]
distinguished_name = dn
prompt = no
[dn]
[root]
basicConstraints = critical, CA:TRUE
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
subjectKeyIdentifier = DE:AD:BE:EF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF
[ca]
basicConstraints = critical, CA:TRUE
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid
[leaf]
basicConstraints = critical, CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:leaf.example.com
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid
CNF

# $1 key-path $2 out
root(){
openssl req -new -x509 -key "$1" -subj "/O=Test/CN=Root" \
-days 7300 -sha256 -set_serial 1 -config "$WORK/ext.cnf" \
-extensions root -out "$2"
}

# $1 key-path $2 CN $3 issuer-cert $4 issuer-key-path $5 ext $6 out $7 serial
child(){
openssl req -new -key "$1" -subj "/O=Test/CN=$2" \
-config "$WORK/ext.cnf" -out "$WORK/c.csr"
openssl x509 -req -in "$WORK/c.csr" -CA "$3" -CAkey "$4" \
-set_serial "$7" -days 7300 -sha256 -extfile "$WORK/ext.cnf" \
-extensions "$5" -out "$6"
}

for k in realRoot evilRoot attackerCA intermediate; do
openssl genrsa -out "$WORK/$k-key.pem" 2048
done
openssl genrsa -out "$DIR/leaf-key.pem" 2048

root "$WORK/realRoot-key.pem" "$DIR/realRoot-cert.pem"
root "$WORK/evilRoot-key.pem" "$WORK/evilRoot-cert.pem"
child "$WORK/attackerCA-key.pem" Attacker "$WORK/evilRoot-cert.pem" \
"$WORK/evilRoot-key.pem" ca "$WORK/attackerCA-cert.pem" 2
openssl req -new -x509 -key "$WORK/intermediate-key.pem" \
-subj "/O=Test/CN=Intermediate" -days 7300 -sha256 -set_serial 3 \
-config "$WORK/ext.cnf" -extensions ca -out "$WORK/intermediate-cert.pem"
child "$DIR/leaf-key.pem" leaf.example.com "$WORK/attackerCA-cert.pem" \
"$WORK/attackerCA-key.pem" leaf "$WORK/leaf-cert.pem" 4

cat "$WORK/leaf-cert.pem" "$WORK/intermediate-cert.pem" \
"$WORK/attackerCA-cert.pem" > "$DIR/server-chain.pem"
echo "Done"
28 changes: 28 additions & 0 deletions certs/test/alt-chain-forged-ca/leaf-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHqNwFqKxe/AEZ
VWZaHNniBMakNXNx7mtE1sV2+GrdkJQE5MLzpXAvjdPJtS6NuQPgBWvm8dAyYC7o
gBXSPFdvy2XwiJan1hEycgivINNbLYNmDS1PZK4XfNNqYupySA+hcIhmujkXKfut
WdivXlaOx0YUpw3XZpphd9Ry9aJ1Tn49jMb4zUXoGtZ8CvudLCdlcu5pXFwQqBfu
hX5K/f0y1v3ho1F4DJaTOEhXyH00vEZpJL/kbGW0lgymTkltZmm0LX9Judt+O3Zi
pT/RSQ+4fqHuvLH3ndGfJifZ3rodoerDbWlR/s+CWGO14zSugV39QLRh6xHgmbRU
i5mguhUzAgMBAAECggEAAzghFnarrNTLk1dLd3yxzXfXpUv270MLKyJHyQBkmYT1
9gXWpN7c6hwtA+2uPfrznPGWPBq+PImzex+eYNqE0f8jRvEU2/wfukLMPaXXjC4c
L8TBOPkxG2mkvDlMrKIMnat2vF1LtvVmb8GcNLVEy2soIWrq7+p65vZrkDaPGezh
e2WI30saRLK0mFsJYOJ7IpD0WOcZWA/9QKBPxXpBkeGf8MJbujiHXAtLk6BXn19o
A2CfuXcYkamkXh48/R8ENu75i2PXqoRqX+TldcQcNXwQA5/el50So8ur2Bg1Jhfb
/Iig8X4rVKhrlpWgE+iSu0BooOjvUmEj9chjflXVTQKBgQDla4HuSbwYCCGoXiR9
mTfl5V+yz/QYHsq+H8Lw2fUJicgRRVO1TMmoGNP+C0BeVp9JKnoPK1ZdlDvYuu7n
01XIJ9u/VBv13/b0s+QaCuAoN4AnO0a5jWKMRPp+65YBPhIUiHJBpQX2870+u6nM
vYnyWlc3FSRrlOLaYFY+XFUHfQKBgQDeyqxraolshiwtpEa8P3COevESA1BRhVjB
nScwfNOYBvYDp1vGYFoe9iza8wjxzY9Et20bP7sy5VvFKod/mpjAFeEUDsRUohmO
IfU4m6hPjrBZfWQ7jOI54Gf5UnjG2glJ3VF6pVA/uwZb8idRbUJ2zHmLUoz7sLLq
yR9Ej68ObwKBgG15jKnRo6DwGGeIbO9GMudQOgdQtlDgOKza6SIXT5d6mO6s31Hv
T3cYSei7I78gpKe8Tjx42KCVAK3eHeyf6xo08uZs017TvbttMBbBQ8/NFCkkXw5i
CjmXHNV9w7naDbSgm6z5e0wpaQ/Lay5Y77+nHmEZhKSVil7cg6sEUkrdAoGAKkvb
9ACj2mCWnoujijWZDtO0VLEgXHmuYgON3xyzpxcbOZJaUA0Wzu35kg+10QIvguI3
6oZs6bq1c3chhk45Va5Rrtcm2tJze5Ji1b5nc8MpI7Q0hUG36Tj7RFAt8cKPJODJ
iTk9RPwitu4AHOtbROaI5LRlY5smPIC2WPPWTi0CgYAyMSUMrKoHp9HKthk6pErV
+u7t8qOjq7+l+/dX25GKQxoSu8SGNSI1uQSzHjD7Fs6yMqolerIHZo8/+PGXWIYh
j/b6PIneLhlRtYbatYbA8e38Peu4eqUSZG7SixjcJLZSoIxFhgtPpR+PfTTGlgQa
CneNQ6VLSbsPw2jpwNLf4Q==
-----END PRIVATE KEY-----
18 changes: 18 additions & 0 deletions certs/test/alt-chain-forged-ca/realRoot-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC+TCCAeGgAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMQ0wCwYDVQQKDARUZXN0
MQ0wCwYDVQQDDARSb290MB4XDTI2MTEwNTIyMDQzNloXDTQ2MTAzMTIyMDQzNlow
HjENMAsGA1UECgwEVGVzdDENMAsGA1UEAwwEUm9vdDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAJcCodfd6jQD404Bp2L6Oi5SWRUQVvmGCN08P9FdoBT+
CPoW9txRzXQ4jJcNUbD9+gcQm1NhNn1IS/rHE4ITWt5Gf2YaQnQkXUz6YdAZlSeO
TSV8abDp3fF4qLXlMyRtbDXShy3U4RAsNWd0Eu19/b9zWnGGRmA4v2ElFUmsYw4R
l1L48X+pX8XTQAg8RFGoryGgf3SuINR4qFkODFD5T5+GtkRPFbz8Tiztm3I7unY4
l28RsWMQ++uQ+aPGa0ZxOmf3Mv4daBnZzWt6nYKyOp6Sx1V7ssDI5+MvFbtEC785
3eRm/dYDBWLm5jPQMMNibrUHvAbT/jNL/T6lbM7TNvECAwEAAaNCMEAwDwYDVR0T
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFN6tvu8AESIzRFVm
d4iZqrvM3e7/MA0GCSqGSIb3DQEBCwUAA4IBAQAQgpJ4KYMDe0sVloDcQKxTnuXX
+B48VP1YodWwpPZiRsokl9wxJ/bzaCTNPragH40PSouLwwxrsLVEC/PYzHlnW5lO
XGHXxnB35l0KcNpAef2oBb5z18WkkpgW1r0WGP2ns0ZG4yL6uN2Lb5qKtNnfPqHH
wpF08n2Emxjk5WRWI7jwZDA25MrGSMge5WnG+e+EdSED652zglTXmLtdwJESSEqg
XfsswK+cbMQeNh0hGKQhzfoUHTwB6g2/eFesgNKHQR4yAolbFGJ8LqMIDVOzBFIj
WQcIEPloNI5k7YBMOjVf3+eDoGUVVus4to+lUGwkr/tOrfFpiT3DRGYQEuD5
-----END CERTIFICATE-----
58 changes: 58 additions & 0 deletions certs/test/alt-chain-forged-ca/server-chain.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
-----BEGIN CERTIFICATE-----
MIIDWzCCAkOgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAiMQ0wCwYDVQQKDARUZXN0
MREwDwYDVQQDDAhBdHRhY2tlcjAeFw0yNjExMDUyMjA0MzZaFw00NjEwMzEyMjA0
MzZaMCoxDTALBgNVBAoMBFRlc3QxGTAXBgNVBAMMEGxlYWYuZXhhbXBsZS5jb20w
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHqNwFqKxe/AEZVWZaHNni
BMakNXNx7mtE1sV2+GrdkJQE5MLzpXAvjdPJtS6NuQPgBWvm8dAyYC7ogBXSPFdv
y2XwiJan1hEycgivINNbLYNmDS1PZK4XfNNqYupySA+hcIhmujkXKfutWdivXlaO
x0YUpw3XZpphd9Ry9aJ1Tn49jMb4zUXoGtZ8CvudLCdlcu5pXFwQqBfuhX5K/f0y
1v3ho1F4DJaTOEhXyH00vEZpJL/kbGW0lgymTkltZmm0LX9Judt+O3ZipT/RSQ+4
fqHuvLH3ndGfJifZ3rodoerDbWlR/s+CWGO14zSugV39QLRh6xHgmbRUi5mguhUz
AgMBAAGjgZMwgZAwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0l
BAwwCgYIKwYBBQUHAwEwGwYDVR0RBBQwEoIQbGVhZi5leGFtcGxlLmNvbTAdBgNV
HQ4EFgQUZWEHg66piqeBE79Yh++du4czvuEwHwYDVR0jBBgwFoAUIQq1riRwrOOl
Lf8TAmqaOC3UasYwDQYJKoZIhvcNAQELBQADggEBAGlQh2YNCTasmEy+B+Lre8FT
JhYUXFB7vYj6/0bkkiivf+DH++m3My13DDTgBWU6MaZWos7EJkDTsk1zeEkagU0W
bDyj+Rbv2wbYWRD+ePWXJ/Mlum+gQ9Pb6Gk+p71DWLTHxqTxe+GUuz72liLyHOOE
Wf/9aXd2pEchbsoAE/MLgjkR9ZXoUIGn1xz73LgX0OkfU6G27+0LILngmdgG1vFS
+niQ9uoJreqqRA6Ux8fdwt/dDrbR5jj6BameFXG/aPwXX7rVvxPaiRDUcuS7yWfj
hCWm3K6XzB0zw1QWvWdXjo1vBg2zD8qxcc1iKpplO57X6n7byEhbsD07voAcqnA=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAmMQ0wCwYDVQQKDARUZXN0
MRUwEwYDVQQDDAxJbnRlcm1lZGlhdGUwHhcNMjYxMTA1MjIwNDM2WhcNNDYxMDMx
MjIwNDM2WjAmMQ0wCwYDVQQKDARUZXN0MRUwEwYDVQQDDAxJbnRlcm1lZGlhdGUw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+2lHDnIc9TZztNLvfHt0J
6F5n+l4djINJlO7qm0ionlAUxXGQ/yBD7tE4u7isVQdpTu8GVgMvFlzhRXGywtMW
WzQfmDhb5L44ImGvvzpBHg3PUoS6PfjCPetAQr3y2ffzZZb23inN/BkXKXyHxu/n
FkOZhC7XQPF2a0/Asux+ML8Y7bXZlkFGW7PHvWLgb2yIiR3l0/YN296jNtqv8k4z
sZGwscuQbcO2OYx64w7LuHb2t39K3y/l0AW2RizEOVme0RS1L9tqL6etPjRclw8w
rnI+Rvbm4vYNnT8Rr6oHmCbMbyaVVdgi9bAomDqBdECb8W95XQns0NjOOLfKkj99
AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1Ud
DgQWBBQi1spsbHe3+fvuV6UCgLLcbyMwljANBgkqhkiG9w0BAQsFAAOCAQEAHWnP
efm8loo+GdhBAYqkx9WzI6GdTSL+NqA5n5gvFN/IHvWq0lKO8/NKhGLYAiwxgT9g
89ou9s8P6fQfakhKIv9SKh94pPNzGwAMMY5hERf56ia6lbUDm19XzOf/R20tx6tg
SStOqdbOML2/Pl1psUTWTzKr/KwmE/5kDvuinuXPccQ/Plq8n7BofuZiZA6xn9B+
VETMynOl4zaEEN09cKSaOB76oq02chsFNwMjNy7WUy9w2XiuewSOCX1+l9q/HXSB
b8cD22aeScGDMFVc31BAvn5jG0G25aLBF3G3IbCm/VstR1S6PHIhya+29NMbEfG/
JGwx+TKcPMbOHSZ5vA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDHjCCAgagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAeMQ0wCwYDVQQKDARUZXN0
MQ0wCwYDVQQDDARSb290MB4XDTI2MTEwNTIyMDQzNloXDTQ2MTAzMTIyMDQzNlow
IjENMAsGA1UECgwEVGVzdDERMA8GA1UEAwwIQXR0YWNrZXIwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQClhVsnbALuXcBp9QsI6Fx+gaaugUtmh6KrvYfL
Ydip3MoifFI/UcYk70CHBYzF7hPUzkn10dRZqma4mOkBQ3etL2evEvUZUhsXTVLI
ogRFton4u5XBsdn6fBK0j9ytjdPZcPuPQNtyxj6IXLEPZpAfT0iOOHHzunWPDEpG
T3+DVjUkTt+rWNgPur8FdbOU8iDT11L3eSdoQRQUbavCM5+fiQGSw22iF3iZ7Y6j
breCyRSKCV6fvajHvulU6UgxnOm4hGAc6atHUuKc0NqCPdziIyz7qlIr5CZxecOg
MeaQqWkqhcJUtt5Mmu0Ph5KYH0ydbDbzRQW3L0Vw5BDJwqjrAgMBAAGjYzBhMA8G
A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQhCrWuJHCs
46Ut/xMCapo4LdRqxjAfBgNVHSMEGDAWgBTerb7vABEiM0RVZneImaq7zN3u/zAN
BgkqhkiG9w0BAQsFAAOCAQEAs9WndeHFpWEXSHYYdWJUU4fewSvGQLfAU0ZYF6Vf
bb7g2OkZc8yW3bQwV0oZUrHHfJUpMimabV21YXAjbbHDYs4iGmGGAxKHst5JSxPK
MYwn4QNr2lzsqcO6qYqsf8jJMR86B+pBvkPLU/bIY15MMzks+9mGqSyoj56UBO6n
dlu9EC+6aMX1sH51Z8sNWM+Z0OcfEv6/1NdXJdgapbfLmZT8dzmUsZ1/sO4KoToD
F54+AIllAUHC2qgAn9KjWba4xtQ0BYaHiDMBRdCZfFZoieyme93SoSYsADIbwZN+
Rd6BEXGa83TNqC/PWmJGcl3F1G+e01ssvsavBHwD9Ty9MA==
-----END CERTIFICATE-----
6 changes: 6 additions & 0 deletions certs/test/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,9 @@ EXTRA_DIST += \
certs/test/nc-ancestor/03-leaf-chain.pem \
certs/test/nc-ancestor/03-valid-leaf-cert.pem \
certs/test/nc-ancestor/03-valid-leaf-key.pem

EXTRA_DIST += \
certs/test/alt-chain-forged-ca/gen-alt-chain-forged-ca.sh \
certs/test/alt-chain-forged-ca/realRoot-cert.pem \
certs/test/alt-chain-forged-ca/leaf-key.pem \
certs/test/alt-chain-forged-ca/server-chain.pem
20 changes: 16 additions & 4 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -19873,6 +19873,13 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
&& !args->haveTrustPeer
#endif /* WOLFSSL_TRUST_PEER_CERT */
) {
#if (defined(WOLFSSL_ALT_CERT_CHAINS) || \
(defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS))) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
/* Error recorded by earlier certs, restored when this
* cert's CA error below is bypassed instead of wiped. */
unsigned long peerVerifyRet = ssl->peerVerifyRet;
#endif
int skipAddCA = 0;
#if defined(HAVE_OCSP) && defined(HAVE_CRL)
int ocspNoUrl = 0;
Expand Down Expand Up @@ -20171,10 +20178,13 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
}

ret = 0; /* clear errors and continue */
/* Only this cert's error is waived. Keep the
* errors from earlier certs, including
* args->verifyErr, so the chain is still
* rejected if it should be. */
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
ssl->peerVerifyRet = 0;
ssl->peerVerifyRet = peerVerifyRet;
#endif
args->verifyErr = 0;

/* do not add to certificate manager */
skipAddCA = 1;
Expand Down Expand Up @@ -20209,10 +20219,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
WOLFSSL_MSG("Bypassing errors to allow for Apple native"
" CA validation");
ret = 0; /* clear errors and continue */
args->verifyErr = 0;
/* Only this cert's error is waived. Keep the errors
* from earlier certs, including args->verifyErr, so
* the chain is still rejected if it should be. */
#if defined(OPENSSL_EXTRA) \
|| defined(OPENSSL_EXTRA_X509_SMALL)
ssl->peerVerifyRet = 0;
ssl->peerVerifyRet = peerVerifyRet;
#endif
/* do not add to certificate manager */
skipAddCA = 1;
Expand Down
140 changes: 140 additions & 0 deletions tests/api/test_ssl_cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -3978,6 +3978,146 @@ int test_wolfSSL_chain_ca_ext_key_usage(void)
return EXPECT_RESULT();
}

#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
defined(WOLFSSL_ALT_CERT_CHAINS) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_PEM_TO_DER) && !defined(NO_RSA) && !defined(NO_TLS) && \
!defined(NO_SHA256) && !defined(NO_FILESYSTEM) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
static int test_alt_chain_forged_ca_cb_calls;

/* Accept every certificate and leave the decision to
* wolfSSL_get_verify_result() once the handshake is done. */
static int test_alt_chain_forged_ca_cb(int preverify,
WOLFSSL_X509_STORE_CTX* store)
{
(void)preverify;
(void)store;
test_alt_chain_forged_ca_cb_calls++;
return 1;
}

#ifndef NO_WOLFSSL_CM_VERIFY
static int test_alt_chain_forged_ca_cm_calls;

/* Certificate manager callback that rejects every certificate that failed. */
static int test_alt_chain_forged_ca_cm_cb(int preverify,
WOLFSSL_X509_STORE_CTX* store)
{
(void)store;
test_alt_chain_forged_ca_cm_calls++;
return preverify;
}
#endif
#endif

/* Test that bypassing a CA error for the alternate certificate chain does not
* also erase an error recorded by an earlier certificate in the chain.
*
* The server sends leaf, intermediate, attackerCA. attackerCA names the
* trusted root as its issuer, with a matching AKID, but is signed by another
* key, so its signature check fails. The intermediate is an unrelated
* self-signed CA, so it fails with ASN_SELF_SIGNED_E, which the alternate
* chain code bypasses. The leaf is issued by attackerCA.
*
* Cases:
* 0. No callback: the forged chain is refused.
* 1. A verify callback accepts every certificate and then checks
* wolfSSL_get_verify_result(). That must report the forged CA's
* WOLFSSL_X509_V_ERR_INVALID_CA. Before the fix, the intermediate's
* bypass reset peerVerifyRet to 0, so the leaf was reported as verified.
* 2. A certificate manager callback rejects the forged CA but the verify
* callback overrides the error, so the chain carries on with
* args->verifyErr set. The handshake must still fail at the leaf. Before
* the fix, the intermediate's bypass cleared args->verifyErr and the
* handshake completed.
*
* @return TEST_SUCCESS on success.
*/
int test_wolfSSL_alt_chain_forged_ca(void)
{
EXPECT_DECLS;
#if defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && \
defined(WOLFSSL_ALT_CERT_CHAINS) && defined(OPENSSL_EXTRA) && \
defined(WOLFSSL_PEM_TO_DER) && !defined(NO_RSA) && !defined(NO_TLS) && \
!defined(NO_SHA256) && !defined(NO_FILESYSTEM) && \
!defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
const char* rootFile =
"./certs/test/alt-chain-forged-ca/realRoot-cert.pem";
const char* chainFile =
"./certs/test/alt-chain-forged-ca/server-chain.pem";
const char* keyFile =
"./certs/test/alt-chain-forged-ca/leaf-key.pem";
WOLFSSL_CTX *ctx_c = NULL, *ctx_s = NULL;
WOLFSSL *ssl_c = NULL, *ssl_s = NULL;
struct test_memio_ctx test_ctx;
int mode;
#ifndef NO_WOLFSSL_CM_VERIFY
const int lastMode = 2;
#else
const int lastMode = 1;
#endif

for (mode = 0; mode <= lastMode && EXPECT_SUCCESS(); mode++) {
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
ExpectIntEQ(test_memio_setup(&test_ctx, &ctx_c, &ctx_s, &ssl_c,
&ssl_s, wolfSSLv23_client_method, wolfSSLv23_server_method), 0);

ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx_c, rootFile, NULL),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_use_certificate_chain_file(ssl_s, chainFile),
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_use_PrivateKey_file(ssl_s, keyFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);

if (mode == 0) {
/* Without a callback the forged chain must be refused. */
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_PEER, NULL);
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectIntNE(wolfSSL_get_verify_result(ssl_c), WOLFSSL_X509_V_OK);
}
else if (mode == 1) {
test_alt_chain_forged_ca_cb_calls = 0;
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_PEER,
test_alt_chain_forged_ca_cb);
/* The callback waives every error, so the handshake completes,
* but the forged CA's error must still be reported. */
ExpectIntEQ(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectIntGT(test_alt_chain_forged_ca_cb_calls, 0);
ExpectIntEQ(wolfSSL_get_verify_result(ssl_c),
WOLFSSL_X509_V_ERR_INVALID_CA);
}
#ifndef NO_WOLFSSL_CM_VERIFY
else {
test_alt_chain_forged_ca_cb_calls = 0;
test_alt_chain_forged_ca_cm_calls = 0;
if (ctx_c != NULL) {
wolfSSL_CertManagerSetVerify(
wolfSSL_CTX_GetCertManager(ctx_c),
test_alt_chain_forged_ca_cm_cb);
}
wolfSSL_set_verify(ssl_c, WOLFSSL_VERIFY_PEER,
test_alt_chain_forged_ca_cb);
/* The certificate manager's rejection of the forged CA must
* survive the intermediate's bypass and fail the leaf. */
ExpectIntNE(test_memio_do_handshake(ssl_c, ssl_s, 10, NULL), 0);
ExpectIntGT(test_alt_chain_forged_ca_cm_calls, 0);
ExpectIntGT(test_alt_chain_forged_ca_cb_calls, 0);
}
#endif

wolfSSL_free(ssl_c);
ssl_c = NULL;
wolfSSL_free(ssl_s);
ssl_s = NULL;
wolfSSL_CTX_free(ctx_c);
ctx_c = NULL;
wolfSSL_CTX_free(ctx_s);
ctx_s = NULL;
}
#endif
return EXPECT_RESULT();
}

#if defined(WOLFSSL_SMALL_CERT_VERIFY) && \
defined(HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES) && !defined(NO_RSA) && \
!defined(NO_TLS) && !defined(NO_SHA256) && !defined(NO_ASN_TIME) && \
Expand Down
Loading
Loading