mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
RPK: Define Certificates correctly for (D)TLS1.2
As per https://datatracker.ietf.org/doc/html/rfc7250#section-3 Figure 1, the RPK is a single ASN.1_subjectPublicKeyInfo, whereas X509 certificates etc. are transmitted as a certificate list (even if there is only 1). This is for (D)TLS1.2 transfers, and this PR fixes this. As per https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2 all certificates (both RPK and Z509) are transferred using a certificate list. Update examples client to support RPK certificates. For testing:- Server: $ gnutls-serv --http --x509fmtder --priority NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK --rawpkfile certs/server-keyPub.der --rawpkkeyfile certs/server-key.der Client: $ examples/client/client -g -p 5556 -c certs/client-keyPub.der -k certs/client-key.der --rpk --files-are-der
This commit is contained in:
@ -1103,7 +1103,7 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
|
||||
/* 4. add the same message into Japanese section */
|
||||
/* (will be translated later) */
|
||||
/* 5. add printf() into suitable position of Usage() */
|
||||
static const char* client_usage_msg[][75] = {
|
||||
static const char* client_usage_msg[][78] = {
|
||||
/* English */
|
||||
{
|
||||
" NOTE: All files relative to wolfSSL home dir\n", /* 0 */
|
||||
@ -1318,9 +1318,13 @@ static const char* client_usage_msg[][75] = {
|
||||
#ifndef NO_PSK
|
||||
"--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 74 */
|
||||
#endif
|
||||
#ifdef HAVE_RPK
|
||||
"--rpk Use RPK for the defined certificates\n", /* 75 */
|
||||
#endif
|
||||
"--files-are-der Specified files are in DER, not PEM format\n", /* 76 */
|
||||
"\n"
|
||||
"For simpler wolfSSL TLS client examples, visit\n"
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 75 */
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */
|
||||
NULL,
|
||||
},
|
||||
#ifndef NO_MULTIBYTE_PRINT
|
||||
@ -1542,10 +1546,14 @@ static const char* client_usage_msg[][75] = {
|
||||
#ifndef NO_PSK
|
||||
"--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 74 */
|
||||
#endif
|
||||
#ifdef HAVE_RPK
|
||||
"--rpk Use RPK for the defined certificates\n", /* 75 */
|
||||
#endif
|
||||
"--files-are-der Specified files are in DER, not PEM format\n", /* 76 */
|
||||
"\n"
|
||||
"より簡単なwolfSSL TLS クライアントの例については"
|
||||
"下記にアクセスしてください\n"
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 75 */
|
||||
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */
|
||||
NULL,
|
||||
},
|
||||
#endif
|
||||
@ -1763,9 +1771,9 @@ static void Usage(void)
|
||||
printf("%s", msg[++msgid]); /* Examples repo link */
|
||||
#ifdef HAVE_PQC
|
||||
printf("%s", msg[++msgid]); /* --pqc */
|
||||
printf("%s", msg[++msgid]); /* --pqc options */
|
||||
printf("%s", msg[++msgid]); /* more --pqc options */
|
||||
printf("%s", msg[++msgid]); /* more --pqc options */
|
||||
#endif
|
||||
#ifdef WOLFSSL_SRTP
|
||||
printf("%s", msg[++msgid]); /* dtls-srtp */
|
||||
#endif
|
||||
#ifdef WOLFSSL_SYS_CA_CERTS
|
||||
printf("%s", msg[++msgid]); /* --sys-ca-certs */
|
||||
@ -1773,9 +1781,14 @@ static void Usage(void)
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
printf("%s", msg[++msgid]); /* --onlyPskDheKe */
|
||||
#endif
|
||||
#ifdef WOLFSSL_SRTP
|
||||
printf("%s", msg[++msgid]); /* dtls-srtp */
|
||||
#ifndef NO_PSK
|
||||
printf("%s", msg[++msgid]); /* --openssl-psk */
|
||||
#endif
|
||||
#ifdef HAVE_RPK
|
||||
printf("%s", msg[++msgid]); /* --rpk */
|
||||
#endif
|
||||
printf("%s", msg[++msgid]); /* --files-are-der */
|
||||
printf("%s", msg[++msgid]); /* Documentation Hint */
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SRTP
|
||||
@ -1919,6 +1932,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
{ "openssl-psk", 0, 265 },
|
||||
#endif
|
||||
{ "quieter", 0, 266 },
|
||||
#ifdef HAVE_RPK
|
||||
{ "rpk", 0, 267 },
|
||||
#endif /* HAVE_RPK */
|
||||
{ "files-are-der", 0, 268 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
#endif
|
||||
@ -2059,6 +2076,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
int useDtlsCID = 0;
|
||||
char dtlsCID[DTLS_CID_BUFFER_SIZE] = { 0 };
|
||||
#endif /* WOLFSSL_DTLS_CID */
|
||||
#ifdef HAVE_RPK
|
||||
int useRPK = 0;
|
||||
#endif /* HAVE_RPK */
|
||||
int fileFormat = WOLFSSL_FILETYPE_PEM;
|
||||
|
||||
char buffer[WOLFSSL_MAX_ERROR_SZ];
|
||||
|
||||
@ -2756,6 +2777,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
case 266:
|
||||
quieter = 1;
|
||||
break;
|
||||
case 267:
|
||||
#ifdef HAVE_RPK
|
||||
useRPK = 1;
|
||||
#endif /* HAVE_RPK */
|
||||
break;
|
||||
case 268:
|
||||
fileFormat = WOLFSSL_FILETYPE_ASN1;
|
||||
break;
|
||||
default:
|
||||
Usage();
|
||||
XEXIT_T(MY_EX_USAGE);
|
||||
@ -3129,6 +3158,21 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RPK
|
||||
if (useRPK) {
|
||||
char ctype[] = {WOLFSSL_CERT_TYPE_RPK};
|
||||
char stype[] = {WOLFSSL_CERT_TYPE_RPK};
|
||||
|
||||
wolfSSL_CTX_set_client_cert_type(ctx, ctype, sizeof(ctype)/sizeof(ctype[0]));
|
||||
wolfSSL_CTX_set_server_cert_type(ctx, stype, sizeof(stype)/sizeof(stype[0]));
|
||||
usePsk = 0;
|
||||
#ifdef HAVE_CRL
|
||||
disableCRL = 1;
|
||||
#endif
|
||||
doPeerCheck = 0;
|
||||
}
|
||||
#endif /* HAVE_RPK */
|
||||
|
||||
if (usePsk) {
|
||||
#ifndef NO_PSK
|
||||
const char *defaultCipherList = cipherList;
|
||||
@ -3261,7 +3305,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
|
||||
err_sys("can't load client cert buffer");
|
||||
#elif !defined(TEST_LOAD_BUFFER)
|
||||
if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert)
|
||||
if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, ourCert, fileFormat)
|
||||
!= WOLFSSL_SUCCESS) {
|
||||
wolfSSL_CTX_free(ctx); ctx = NULL;
|
||||
err_sys("can't load client cert file, check file and run from"
|
||||
@ -3285,7 +3329,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
|
||||
err_sys("can't load client private key buffer");
|
||||
#elif !defined(TEST_LOAD_BUFFER)
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, WOLFSSL_FILETYPE_PEM)
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, fileFormat)
|
||||
!= WOLFSSL_SUCCESS) {
|
||||
wolfSSL_CTX_free(ctx); ctx = NULL;
|
||||
err_sys("can't load client private key file, check file and run "
|
||||
@ -3593,7 +3637,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
err_sys("can't load client cert buffer");
|
||||
}
|
||||
#elif !defined(TEST_LOAD_BUFFER)
|
||||
if (wolfSSL_use_certificate_chain_file(ssl, ourCert)
|
||||
if (wolfSSL_use_certificate_chain_file_format(ssl, ourCert, fileFormat)
|
||||
!= WOLFSSL_SUCCESS) {
|
||||
wolfSSL_CTX_free(ctx); ctx = NULL;
|
||||
err_sys("can't load client cert file, check file and run from"
|
||||
@ -3614,7 +3658,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
|
||||
err_sys("can't load client private key buffer");
|
||||
#elif !defined(TEST_LOAD_BUFFER)
|
||||
if (wolfSSL_use_PrivateKey_file(ssl, ourKey, WOLFSSL_FILETYPE_PEM)
|
||||
if (wolfSSL_use_PrivateKey_file(ssl, ourKey, fileFormat)
|
||||
!= WOLFSSL_SUCCESS) {
|
||||
wolfSSL_CTX_free(ctx); ctx = NULL;
|
||||
err_sys("can't load client private key file, check file and run "
|
||||
|
@ -14288,7 +14288,25 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
ERROR_OUT(BUFFER_ERROR, exit_ppc);
|
||||
}
|
||||
c24to32(input + args->idx, &listSz);
|
||||
args->idx += OPAQUE24_LEN;
|
||||
#ifdef HAVE_RPK
|
||||
/*
|
||||
* If this is RPK from the peer, then single cert (if TLS1.2).
|
||||
* So, ListSz location is same as CertSz location, so fake
|
||||
* we have just seen this ListSz.
|
||||
*/
|
||||
if (!IsAtLeastTLSv1_3(ssl->version) &&
|
||||
((ssl->options.side == WOLFSSL_SERVER_END &&
|
||||
ssl->options.rpkState.received_ClientCertTypeCnt == 1 &&
|
||||
ssl->options.rpkState.received_ClientCertTypes[0] == WOLFSSL_CERT_TYPE_RPK) ||
|
||||
(ssl->options.side == WOLFSSL_CLIENT_END &&
|
||||
ssl->options.rpkState.received_ServerCertTypeCnt == 1 &&
|
||||
ssl->options.rpkState.received_ServerCertTypes[0] == WOLFSSL_CERT_TYPE_RPK))) {
|
||||
listSz += OPAQUE24_LEN;
|
||||
} else
|
||||
#endif /* HAVE_RPK */
|
||||
{
|
||||
args->idx += OPAQUE24_LEN;
|
||||
}
|
||||
if (listSz > MAX_CERTIFICATE_SZ) {
|
||||
ERROR_OUT(BUFFER_ERROR, exit_ppc);
|
||||
}
|
||||
@ -23076,6 +23094,9 @@ int SendCertificate(WOLFSSL* ssl)
|
||||
int ret = 0;
|
||||
word32 certSz, certChainSz, headerSz, listSz, payloadSz;
|
||||
word32 length, maxFragment;
|
||||
#ifdef HAVE_RPK
|
||||
int usingRpkTls12 = 0;
|
||||
#endif /* HAVE_RPK */
|
||||
|
||||
WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND);
|
||||
WOLFSSL_ENTER("SendCertificate");
|
||||
@ -23085,6 +23106,21 @@ int SendCertificate(WOLFSSL* ssl)
|
||||
return 0; /* not needed */
|
||||
}
|
||||
|
||||
#ifdef HAVE_RPK
|
||||
if (!IsAtLeastTLSv1_3(ssl->version)) {
|
||||
/* If this is (D)TLS1.2 and RPK, then single cert, not list. */
|
||||
if (ssl->options.side == WOLFSSL_SERVER_END) {
|
||||
if (ssl->options.rpkState.sending_ServerCertTypeCnt == 1 &&
|
||||
ssl->options.rpkState.sending_ServerCertTypes[0] == WOLFSSL_CERT_TYPE_RPK)
|
||||
usingRpkTls12 = 1;
|
||||
} else if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
if (ssl->options.rpkState.sending_ClientCertTypeCnt == 1 &&
|
||||
ssl->options.rpkState.sending_ClientCertTypes[0] == WOLFSSL_CERT_TYPE_RPK)
|
||||
usingRpkTls12 = 1;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_RPK */
|
||||
|
||||
if (ssl->options.sendVerify == SEND_BLANK_CERT) {
|
||||
#ifdef OPENSSL_EXTRA
|
||||
if (ssl->version.major == SSLv3_MAJOR
|
||||
@ -23107,10 +23143,19 @@ int SendCertificate(WOLFSSL* ssl)
|
||||
return BUFFER_ERROR;
|
||||
}
|
||||
certSz = ssl->buffers.certificate->length;
|
||||
headerSz = 2 * CERT_HEADER_SZ;
|
||||
#ifdef HAVE_RPK
|
||||
if (usingRpkTls12) {
|
||||
headerSz = 1 * CERT_HEADER_SZ;
|
||||
listSz = certSz;
|
||||
} else {
|
||||
#endif /* HAVE_RPK */
|
||||
headerSz = 2 * CERT_HEADER_SZ;
|
||||
listSz = certSz + CERT_HEADER_SZ;
|
||||
#ifdef HAVE_RPK
|
||||
}
|
||||
#endif /* HAVE_RPK */
|
||||
/* list + cert size */
|
||||
length = certSz + headerSz;
|
||||
listSz = certSz + CERT_HEADER_SZ;
|
||||
|
||||
/* may need to send rest of chain, already has leading size(s) */
|
||||
if (certSz && ssl->buffers.certChain) {
|
||||
@ -23203,12 +23248,18 @@ int SendCertificate(WOLFSSL* ssl)
|
||||
}
|
||||
|
||||
/* list total */
|
||||
c32to24(listSz, output + i);
|
||||
if (ssl->options.dtls || !IsEncryptionOn(ssl, 1))
|
||||
HashRaw(ssl, output + i, CERT_HEADER_SZ);
|
||||
i += CERT_HEADER_SZ;
|
||||
length -= CERT_HEADER_SZ;
|
||||
fragSz -= CERT_HEADER_SZ;
|
||||
#ifdef HAVE_RPK
|
||||
if (!usingRpkTls12) {
|
||||
#endif /* HAVE_RPK */
|
||||
c32to24(listSz, output + i);
|
||||
if (ssl->options.dtls || !IsEncryptionOn(ssl, 1))
|
||||
HashRaw(ssl, output + i, CERT_HEADER_SZ);
|
||||
i += CERT_HEADER_SZ;
|
||||
length -= CERT_HEADER_SZ;
|
||||
fragSz -= CERT_HEADER_SZ;
|
||||
#ifdef HAVE_RPK
|
||||
}
|
||||
#endif /* HAVE_RPK */
|
||||
if (certSz) {
|
||||
c32to24(certSz, output + i);
|
||||
if (ssl->options.dtls || !IsEncryptionOn(ssl, 1))
|
||||
|
Reference in New Issue
Block a user