Skip to content

Commit f2e6f49

Browse files
committed
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
1 parent 8970ff4 commit f2e6f49

2 files changed

Lines changed: 116 additions & 21 deletions

File tree

examples/client/client.c

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz,
11031103
/* 4. add the same message into Japanese section */
11041104
/* (will be translated later) */
11051105
/* 5. add printf() into suitable position of Usage() */
1106-
static const char* client_usage_msg[][75] = {
1106+
static const char* client_usage_msg[][78] = {
11071107
/* English */
11081108
{
11091109
" NOTE: All files relative to wolfSSL home dir\n", /* 0 */
@@ -1318,9 +1318,13 @@ static const char* client_usage_msg[][75] = {
13181318
#ifndef NO_PSK
13191319
"--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 74 */
13201320
#endif
1321+
#ifdef HAVE_RPK
1322+
"--rpk Use RPK for the defined certificates\n", /* 75 */
1323+
#endif
1324+
"--files-are-der Specified files are in DER, not PEM format\n", /* 76 */
13211325
"\n"
13221326
"For simpler wolfSSL TLS client examples, visit\n"
1323-
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 75 */
1327+
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */
13241328
NULL,
13251329
},
13261330
#ifndef NO_MULTIBYTE_PRINT
@@ -1542,10 +1546,14 @@ static const char* client_usage_msg[][75] = {
15421546
#ifndef NO_PSK
15431547
"--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 74 */
15441548
#endif
1549+
#ifdef HAVE_RPK
1550+
"--rpk Use RPK for the defined certificates\n", /* 75 */
1551+
#endif
1552+
"--files-are-der Specified files are in DER, not PEM format\n", /* 76 */
15451553
"\n"
15461554
"より簡単なwolfSSL TLS クライアントの例については"
15471555
"下記にアクセスしてください\n"
1548-
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 75 */
1556+
"https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */
15491557
NULL,
15501558
},
15511559
#endif
@@ -1763,19 +1771,24 @@ static void Usage(void)
17631771
printf("%s", msg[++msgid]); /* Examples repo link */
17641772
#ifdef HAVE_PQC
17651773
printf("%s", msg[++msgid]); /* --pqc */
1766-
printf("%s", msg[++msgid]); /* --pqc options */
1767-
printf("%s", msg[++msgid]); /* more --pqc options */
1768-
printf("%s", msg[++msgid]); /* more --pqc options */
1774+
#endif
1775+
#ifdef WOLFSSL_SRTP
1776+
printf("%s", msg[++msgid]); /* dtls-srtp */
17691777
#endif
17701778
#ifdef WOLFSSL_SYS_CA_CERTS
17711779
printf("%s", msg[++msgid]); /* --sys-ca-certs */
17721780
#endif
17731781
#ifdef HAVE_SUPPORTED_CURVES
17741782
printf("%s", msg[++msgid]); /* --onlyPskDheKe */
17751783
#endif
1776-
#ifdef WOLFSSL_SRTP
1777-
printf("%s", msg[++msgid]); /* dtls-srtp */
1784+
#ifndef NO_PSK
1785+
printf("%s", msg[++msgid]); /* --openssl-psk */
17781786
#endif
1787+
#ifdef HAVE_RPK
1788+
printf("%s", msg[++msgid]); /* --rpk */
1789+
#endif
1790+
printf("%s", msg[++msgid]); /* --files-are-der */
1791+
printf("%s", msg[++msgid]); /* Documentation Hint */
17791792
}
17801793

17811794
#ifdef WOLFSSL_SRTP
@@ -1919,6 +1932,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
19191932
{ "openssl-psk", 0, 265 },
19201933
#endif
19211934
{ "quieter", 0, 266 },
1935+
#ifdef HAVE_RPK
1936+
{ "rpk", 0, 267 },
1937+
#endif /* HAVE_RPK */
1938+
{ "files-are-der", 0, 268 },
19221939
{ 0, 0, 0 }
19231940
};
19241941
#endif
@@ -2059,6 +2076,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
20592076
int useDtlsCID = 0;
20602077
char dtlsCID[DTLS_CID_BUFFER_SIZE] = { 0 };
20612078
#endif /* WOLFSSL_DTLS_CID */
2079+
#ifdef HAVE_RPK
2080+
int useRPK = 0;
2081+
#endif /* HAVE_RPK */
2082+
int fileFormat = WOLFSSL_FILETYPE_PEM;
20622083

20632084
char buffer[WOLFSSL_MAX_ERROR_SZ];
20642085

@@ -2756,6 +2777,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
27562777
case 266:
27572778
quieter = 1;
27582779
break;
2780+
case 267:
2781+
#ifdef HAVE_RPK
2782+
useRPK = 1;
2783+
#endif /* HAVE_RPK */
2784+
break;
2785+
case 268:
2786+
fileFormat = WOLFSSL_FILETYPE_ASN1;
2787+
break;
27592788
default:
27602789
Usage();
27612790
XEXIT_T(MY_EX_USAGE);
@@ -3129,6 +3158,21 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
31293158
}
31303159
#endif
31313160

3161+
#ifdef HAVE_RPK
3162+
if (useRPK) {
3163+
char ctype[] = {WOLFSSL_CERT_TYPE_RPK};
3164+
char stype[] = {WOLFSSL_CERT_TYPE_RPK};
3165+
3166+
wolfSSL_CTX_set_client_cert_type(ctx, ctype, sizeof(ctype)/sizeof(ctype[0]));
3167+
wolfSSL_CTX_set_server_cert_type(ctx, stype, sizeof(stype)/sizeof(stype[0]));
3168+
usePsk = 0;
3169+
#ifdef HAVE_CRL
3170+
disableCRL = 1;
3171+
#endif
3172+
doPeerCheck = 0;
3173+
}
3174+
#endif /* HAVE_RPK */
3175+
31323176
if (usePsk) {
31333177
#ifndef NO_PSK
31343178
const char *defaultCipherList = cipherList;
@@ -3261,7 +3305,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
32613305
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
32623306
err_sys("can't load client cert buffer");
32633307
#elif !defined(TEST_LOAD_BUFFER)
3264-
if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert)
3308+
if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, ourCert, fileFormat)
32653309
!= WOLFSSL_SUCCESS) {
32663310
wolfSSL_CTX_free(ctx); ctx = NULL;
32673311
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)
32853329
sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
32863330
err_sys("can't load client private key buffer");
32873331
#elif !defined(TEST_LOAD_BUFFER)
3288-
if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, WOLFSSL_FILETYPE_PEM)
3332+
if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, fileFormat)
32893333
!= WOLFSSL_SUCCESS) {
32903334
wolfSSL_CTX_free(ctx); ctx = NULL;
32913335
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)
35933637
err_sys("can't load client cert buffer");
35943638
}
35953639
#elif !defined(TEST_LOAD_BUFFER)
3596-
if (wolfSSL_use_certificate_chain_file(ssl, ourCert)
3640+
if (wolfSSL_use_certificate_chain_file_format(ssl, ourCert, fileFormat)
35973641
!= WOLFSSL_SUCCESS) {
35983642
wolfSSL_CTX_free(ctx); ctx = NULL;
35993643
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)
36143658
sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
36153659
err_sys("can't load client private key buffer");
36163660
#elif !defined(TEST_LOAD_BUFFER)
3617-
if (wolfSSL_use_PrivateKey_file(ssl, ourKey, WOLFSSL_FILETYPE_PEM)
3661+
if (wolfSSL_use_PrivateKey_file(ssl, ourKey, fileFormat)
36183662
!= WOLFSSL_SUCCESS) {
36193663
wolfSSL_CTX_free(ctx); ctx = NULL;
36203664
err_sys("can't load client private key file, check file and run "

src/internal.c

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14288,7 +14288,25 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1428814288
ERROR_OUT(BUFFER_ERROR, exit_ppc);
1428914289
}
1429014290
c24to32(input + args->idx, &listSz);
14291-
args->idx += OPAQUE24_LEN;
14291+
#ifdef HAVE_RPK
14292+
/*
14293+
* If this is RPK from the peer, then single cert (if TLS1.2).
14294+
* So, ListSz location is same as CertSz location, so fake
14295+
* we have just seen this ListSz.
14296+
*/
14297+
if (!IsAtLeastTLSv1_3(ssl->version) &&
14298+
((ssl->options.side == WOLFSSL_SERVER_END &&
14299+
ssl->options.rpkState.received_ClientCertTypeCnt == 1 &&
14300+
ssl->options.rpkState.received_ClientCertTypes[0] == WOLFSSL_CERT_TYPE_RPK) ||
14301+
(ssl->options.side == WOLFSSL_CLIENT_END &&
14302+
ssl->options.rpkState.received_ServerCertTypeCnt == 1 &&
14303+
ssl->options.rpkState.received_ServerCertTypes[0] == WOLFSSL_CERT_TYPE_RPK))) {
14304+
listSz += OPAQUE24_LEN;
14305+
} else
14306+
#endif /* HAVE_RPK */
14307+
{
14308+
args->idx += OPAQUE24_LEN;
14309+
}
1429214310
if (listSz > MAX_CERTIFICATE_SZ) {
1429314311
ERROR_OUT(BUFFER_ERROR, exit_ppc);
1429414312
}
@@ -23076,6 +23094,9 @@ int SendCertificate(WOLFSSL* ssl)
2307623094
int ret = 0;
2307723095
word32 certSz, certChainSz, headerSz, listSz, payloadSz;
2307823096
word32 length, maxFragment;
23097+
#ifdef HAVE_RPK
23098+
int usingRpkTls12 = 0;
23099+
#endif /* HAVE_RPK */
2307923100

2308023101
WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND);
2308123102
WOLFSSL_ENTER("SendCertificate");
@@ -23085,6 +23106,21 @@ int SendCertificate(WOLFSSL* ssl)
2308523106
return 0; /* not needed */
2308623107
}
2308723108

23109+
#ifdef HAVE_RPK
23110+
if (!IsAtLeastTLSv1_3(ssl->version)) {
23111+
/* If this is (D)TLS1.2 and RPK, then single cert, not list. */
23112+
if (ssl->options.side == WOLFSSL_SERVER_END) {
23113+
if (ssl->options.rpkState.sending_ServerCertTypeCnt == 1 &&
23114+
ssl->options.rpkState.sending_ServerCertTypes[0] == WOLFSSL_CERT_TYPE_RPK)
23115+
usingRpkTls12 = 1;
23116+
} else if (ssl->options.side == WOLFSSL_CLIENT_END) {
23117+
if (ssl->options.rpkState.sending_ClientCertTypeCnt == 1 &&
23118+
ssl->options.rpkState.sending_ClientCertTypes[0] == WOLFSSL_CERT_TYPE_RPK)
23119+
usingRpkTls12 = 1;
23120+
}
23121+
}
23122+
#endif /* HAVE_RPK */
23123+
2308823124
if (ssl->options.sendVerify == SEND_BLANK_CERT) {
2308923125
#ifdef OPENSSL_EXTRA
2309023126
if (ssl->version.major == SSLv3_MAJOR
@@ -23107,10 +23143,19 @@ int SendCertificate(WOLFSSL* ssl)
2310723143
return BUFFER_ERROR;
2310823144
}
2310923145
certSz = ssl->buffers.certificate->length;
23110-
headerSz = 2 * CERT_HEADER_SZ;
23146+
#ifdef HAVE_RPK
23147+
if (usingRpkTls12) {
23148+
headerSz = 1 * CERT_HEADER_SZ;
23149+
listSz = certSz;
23150+
} else {
23151+
#endif /* HAVE_RPK */
23152+
headerSz = 2 * CERT_HEADER_SZ;
23153+
listSz = certSz + CERT_HEADER_SZ;
23154+
#ifdef HAVE_RPK
23155+
}
23156+
#endif /* HAVE_RPK */
2311123157
/* list + cert size */
2311223158
length = certSz + headerSz;
23113-
listSz = certSz + CERT_HEADER_SZ;
2311423159

2311523160
/* may need to send rest of chain, already has leading size(s) */
2311623161
if (certSz && ssl->buffers.certChain) {
@@ -23203,12 +23248,18 @@ int SendCertificate(WOLFSSL* ssl)
2320323248
}
2320423249

2320523250
/* list total */
23206-
c32to24(listSz, output + i);
23207-
if (ssl->options.dtls || !IsEncryptionOn(ssl, 1))
23208-
HashRaw(ssl, output + i, CERT_HEADER_SZ);
23209-
i += CERT_HEADER_SZ;
23210-
length -= CERT_HEADER_SZ;
23211-
fragSz -= CERT_HEADER_SZ;
23251+
#ifdef HAVE_RPK
23252+
if (!usingRpkTls12) {
23253+
#endif /* HAVE_RPK */
23254+
c32to24(listSz, output + i);
23255+
if (ssl->options.dtls || !IsEncryptionOn(ssl, 1))
23256+
HashRaw(ssl, output + i, CERT_HEADER_SZ);
23257+
i += CERT_HEADER_SZ;
23258+
length -= CERT_HEADER_SZ;
23259+
fragSz -= CERT_HEADER_SZ;
23260+
#ifdef HAVE_RPK
23261+
}
23262+
#endif /* HAVE_RPK */
2321223263
if (certSz) {
2321323264
c32to24(certSz, output + i);
2321423265
if (ssl->options.dtls || !IsEncryptionOn(ssl, 1))

0 commit comments

Comments
 (0)