diff --git a/Makefile b/Makefile index c0f20f1..95edec0 100644 --- a/Makefile +++ b/Makefile @@ -219,7 +219,7 @@ test: tests libs: $(MAKE) --directory=core - if $(MAKE) --directory=crypto parse-config | grep -q -e '#define USE_FIPS_CRYPTO' -e '#define USE_CL_CRYPTO'; then $(MAKE) --directory=crypto-cl; else $(MAKE) --directory=crypto; fi + if $(MAKE) --directory=crypto parse-config | grep -q -e '#define USE_FIPS_CRYPTO' -e '#define USE_CL_CRYPTO'; then $(MAKE) --directory=crypto-cl; else if $(MAKE) --directory=crypto parse-config | grep -q -e "#define USE_ROT_CRYPTO"; then $(MAKE) --directory=crypto-rot; else $(MAKE) --directory=crypto; fi; fi if $(MAKE) --directory=crypto parse-config | grep -q '#define USE_CMS'; then $(MAKE) --directory=crypto/cms;fi $(MAKE) --directory=matrixssl if [ -e matrixssh ]; then if $(MAKE) --directory=crypto parse-config | grep -q '#define USE_AES_CTR' && $(MAKE) --directory=crypto parse-config | grep -q '#define USE_DH'; then $(MAKE) --directory=matrixssh;fi;fi @@ -256,6 +256,7 @@ clean: $(MAKE) clean --directory=crypto/test $(MAKE) clean --directory=matrixssl/test if [ -e crypto-cl ]; then $(MAKE) clean --directory=crypto-cl;fi + if [ -e crypto-rot ]; then $(MAKE) clean --directory=crypto-rot;fi if [ -e crypto/cms ]; then $(MAKE) clean --directory=crypto/cms;fi $(MAKE) clean --directory=apps/common $(MAKE) clean --directory=apps/ssl diff --git a/apps/common/clientconfig.c b/apps/common/clientconfig.c index 975ee9f..bfcc0bc 100644 --- a/apps/common/clientconfig.c +++ b/apps/common/clientconfig.c @@ -36,23 +36,29 @@ /* Identity Certs and Keys for use with Client Authentication */ #ifdef ID_RSA #define EXAMPLE_RSA_KEYS -#define EXAMPLE_FILE_KEYS +# ifdef MATRIX_USE_FILE_SYSTEM +# define EXAMPLE_FILE_KEYS static const char rsaCertFile[] = "../../testkeys/RSA/2048_RSA.pem"; static const char rsaPrivkeyFile[] = "../../testkeys/RSA/2048_RSA_KEY.pem"; +# endif #endif #ifdef ID_ECDH_ECDSA #define EXAMPLE_EC_KEYS -#define EXAMPLE_FILE_KEYS +# ifdef MATRIX_USE_FILE_SYSTEM +# define EXAMPLE_FILE_KEYS static const char ecCertFile[] = "../../testkeys/EC/384_EC.pem"; static const char ecPrivkeyFile[] = "../../testkeys/EC/384_EC_KEY.pem"; +# endif #endif #ifdef ID_ECDH_RSA #define EXAMPLE_ECDH_RSA_KEYS -#define EXAMPLE_FILE_KEYS +# ifdef MATRIX_USE_FILE_SYSTEM +# define EXAMPLE_FILE_KEYS static const char ecdhRsaCertFile[] = "../../testkeys/ECDH_RSA/521_ECDH-RSA.pem"; static const char ecdhRsaPrivkeyFile[] = "../../testkeys/ECDH_RSA/521_ECDH-RSA_KEY.pem"; +# endif #endif clientconfig_t g_clientconfig; @@ -99,9 +105,14 @@ void clientconfigInitialize(void) g_clientconfig.default_ca_file = NULL; g_clientconfig.cert_file = NULL; g_clientconfig.privkey_file = NULL; +# ifdef EXAMPLE_FILE_KEYS g_clientconfig.load_key = &loadKeysFromFile; g_clientconfig.loadKeysFromMemory = 0; +# else + g_clientconfig.loadKeysFromMemory = 1; +# endif +# ifdef EXAMPLE_FILE_KEYS # ifdef EXAMPLE_RSA_KEYS g_clientconfig.cert_file = example_file_path(rsaCertFile); g_clientconfig.privkey_file = example_file_path(rsaPrivkeyFile); @@ -127,6 +138,7 @@ void clientconfigInitialize(void) g_clientconfig.load_key = &loadPreSharedKeys; g_clientconfig.loadKeysFromMemory = 1; # endif +# endif # ifdef USE_HEADER_KEYS g_clientconfig.cert_file = NULL; diff --git a/apps/dtls/dtlsClient.c b/apps/dtls/dtlsClient.c index 1193535..02b8720 100644 --- a/apps/dtls/dtlsClient.c +++ b/apps/dtls/dtlsClient.c @@ -269,7 +269,7 @@ READ_MORE: { if (SOCKET_ERRNO != EINTR) { - psTraceIntDtls("unhandled error %d from select", SOCKET_ERRNO); + psTraceInt("unhandled error %d from select", SOCKET_ERRNO); goto L_CLOSE_ERR; } goto READ_MORE; @@ -278,10 +278,10 @@ READ_MORE: if (!FD_ISSET(fd, &readfd)) { /* Timed out. For good? */ - psTraceIntDtls("select timed out %d\n", val); + psTraceInt("select timed out %d\n", val); if (tSec == MAX_WAIT_SECS) { - psTraceDtls("Max Timeout. Leaving\n"); + psTrace("Max Timeout. Leaving\n"); goto L_CLOSE_ERR; } tSec *= 2; @@ -325,7 +325,7 @@ READ_MORE: # ifdef USE_DTLS_DEBUG_TRACE /* nice for debugging */ - psTraceIntDtls("Read %d bytes from server\n", transferred); + psTraceInt("Read %d bytes from server\n", transferred); # endif /* If EOF, remote socket closed. But we haven't received the HTTP response @@ -422,7 +422,7 @@ PROCESS_MORE: /* The second byte is the description */ if (*buf == SSL_ALERT_LEVEL_FATAL) { - psTraceIntInfo("Fatal alert: %d, closing connection.\n", + psTraceInt("Fatal alert: %d, closing connection.\n", *(buf + 1)); goto L_CLOSE_ERR; } @@ -432,7 +432,7 @@ PROCESS_MORE: closeConn(dtlsCtx, fd); return MATRIXSSL_SUCCESS; } - psTraceIntInfo("Warning alert: %d\n", *(buf + 1)); + psTraceInt("Warning alert: %d\n", *(buf + 1)); if ((rc = matrixSslProcessedData(ssl, &buf, (uint32 *) &len)) == 0) { /* No more data in buffer. Might as well read for more. */ @@ -958,7 +958,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert) } } - psTraceStrDtls("Validated cert for: %s.\n", cert->subject.commonName); + psTraceStr("Validated cert for: %s.\n", cert->subject.commonName); # endif /* !USE_ONLY_PSK_CIPHER_SUITE */ return PS_SUCCESS; diff --git a/apps/dtls/dtlsCommon.c b/apps/dtls/dtlsCommon.c index 4095051..7ae78ad 100644 --- a/apps/dtls/dtlsCommon.c +++ b/apps/dtls/dtlsCommon.c @@ -76,7 +76,7 @@ int32 udpSend(SOCKET s, unsigned char *buf, int len, ) { *drop_rehandshake_cipher_spec = 0; - psTraceIntDtls("Didn't send (CHANGE_CIPHER_SPEC flight): %d\n", len); + psTraceInt("Didn't send (CHANGE_CIPHER_SPEC flight): %d\n", len); ++num_dropped; } else @@ -85,7 +85,7 @@ int32 udpSend(SOCKET s, unsigned char *buf, int len, { return -1; } - psTraceIntDtls("Sent %d bytes\n", sent); + psTraceInt("Sent %d bytes\n", sent); } } else @@ -102,7 +102,7 @@ int32 udpSend(SOCKET s, unsigned char *buf, int len, { return -1; } - psTraceIntDtls("Sent %d bytes\n", sent); + psTraceInt("Sent %d bytes\n", sent); } else { @@ -114,11 +114,11 @@ int32 udpSend(SOCKET s, unsigned char *buf, int len, { return -1; } - psTraceIntDtls("Sent %d bytes\n", sent); + psTraceInt("Sent %d bytes\n", sent); } else { - psTraceIntDtls("Didn't send: %d\n", len); + psTraceInt("Didn't send: %d\n", len); ++num_dropped; } } @@ -130,10 +130,10 @@ int32 udpSend(SOCKET s, unsigned char *buf, int len, { return -1; } - psTraceIntDtls("Sent %d bytes\n", sent); + psTraceInt("Sent %d bytes\n", sent); # endif /* DTLS_PACKET_LOSS_TEST */ # ifdef DTLS_PACKET_LOSS_TEST - psTraceIntDtls("%d packets dropped so far\n", + psTraceInt("%d packets dropped so far\n", num_dropped); # endif /* DTLS_PACKET_LOSS_TEST */ return len; diff --git a/apps/dtls/dtlsServer.c b/apps/dtls/dtlsServer.c index a89a850..b4ebb34 100644 --- a/apps/dtls/dtlsServer.c +++ b/apps/dtls/dtlsServer.c @@ -831,7 +831,7 @@ int main(int argc, char **argv) if (val > 0 && FD_ISSET(sock, &readfd)) { - psTraceIntDtls("Select woke %d\n", val); + _psTraceInt("Select woke %d\n", val); /* recvfrom data must always go into generic buffer becuase we don't yet know who it is from */ inaddrlen = sizeof(struct sockaddr_in); @@ -856,7 +856,7 @@ int main(int argc, char **argv) { const char *addrstr; addrstr = getaddrstring((struct sockaddr *) &inaddr, 1); - psTraceIntDtls("Read %d bytes ", recvLen); + _psTraceInt("Read %d bytes ", recvLen); _psTraceStr("from %s\n", (char *) addrstr); psFree(addrstr, NULL); } @@ -868,7 +868,7 @@ int main(int argc, char **argv) { Memset(&options, 0x0, sizeof(sslSessOpts_t)); options.versionFlag = SSL_FLAGS_DTLS; - if (COMPILED_IN_VER(v_dtls_1_2)) + if (v_dtls_1_2 & v_compiled_in) { options.versionFlag |= SSL_FLAGS_TLS_1_2; } @@ -919,7 +919,7 @@ PROCESS_MORE_FROM_BUFFER: to handle this case so we are not resending our final flight */ dtlsCtx->connStatus = RESUMED_HANDSHAKE_COMPLETE; - psTraceDtls("Got HANDSHAKE_COMPLETE out of ReceivedData\n"); + _psTrace("Got HANDSHAKE_COMPLETE out of ReceivedData\n"); break; case MATRIXSSL_APP_DATA: /* Now safe to clear the connStatus flag that was keeping @@ -943,7 +943,7 @@ PROCESS_MORE_FROM_BUFFER: packet_loss_prob, NULL)) < 0) { - psTraceDtls("udpSend error. Ignoring\n"); + _psTrace("udpSend error. Ignoring\n"); } /* Always indicate the entire datagram was sent as there is no way for DTLS to handle partial records. @@ -952,7 +952,7 @@ PROCESS_MORE_FROM_BUFFER: if (rcs == MATRIXSSL_REQUEST_CLOSE) { - psTraceDtls("Got REQUEST_CLOSE out of SentData\n"); + _psTrace("Got REQUEST_CLOSE out of SentData\n"); clearClient(dtlsCtx); break; } @@ -966,14 +966,14 @@ PROCESS_MORE_FROM_BUFFER: } break; case MATRIXSSL_REQUEST_RECV: - psTraceDtls("Got REQUEST_RECV from ReceivedData\n"); + _psTrace("Got REQUEST_RECV from ReceivedData\n"); break; case MATRIXSSL_RECEIVED_ALERT: /* The first byte of the buffer is the level */ /* The second byte is the description */ if (*sslBuf == SSL_ALERT_LEVEL_FATAL) { - psTraceIntDtls("Fatal alert: %d, closing connection.\n", + _psTraceInt("Fatal alert: %d, closing connection.\n", *(sslBuf + 1)); clearClient(dtlsCtx); continue; /* Next connection */ @@ -984,7 +984,7 @@ PROCESS_MORE_FROM_BUFFER: clearClient(dtlsCtx); continue; /* Next connection */ } - psTraceIntDtls("Warning alert: %d\n", *(sslBuf + 1)); + _psTraceInt("Warning alert: %d\n", *(sslBuf + 1)); if ((rcr = matrixSslProcessedData(ssl, &sslBuf, (uint32 *) &freeBufLen)) == 0) { @@ -1000,7 +1000,7 @@ PROCESS_MORE_FROM_BUFFER: { if (SOCKET_ERRNO != EINTR) { - psTraceIntDtls("unhandled error %d from select", SOCKET_ERRNO); + _psTraceInt("unhandled error %d from select", SOCKET_ERRNO); } } /* @@ -1073,7 +1073,7 @@ static int32 handleResends(SOCKET sock) us as complete officially */ if (dtlsCtx->connStatus == RESUMED_HANDSHAKE_COMPLETE) { - psTraceDtls("Connected but awaiting data\n"); + _psTrace("Connected but awaiting data\n"); continue; } ssl = dtlsCtx->ssl; @@ -1087,21 +1087,21 @@ static int32 handleResends(SOCKET sock) packet_loss_prob, NULL)) < 0) { - psTraceDtls("udpSend error. Ignoring\n"); + _psTrace("udpSend error. Ignoring\n"); } /* Always indicate the entire datagram was sent as there is no way for DTLS to handle partial records. Resends and timeouts will handle any problems */ if ((rc = matrixDtlsSentData(ssl, sslBufLen)) < 0) { - psTraceDtls("internal error\n"); + _psTrace("internal error\n"); clearClient(dtlsCtx); clientCount--; break; } if (rc == MATRIXSSL_REQUEST_CLOSE) { - psTraceDtls("Got REQUEST_CLOSE out of SentData\n"); + _psTrace("Got REQUEST_CLOSE out of SentData\n"); clearClient(dtlsCtx); clientCount--; break; @@ -1109,7 +1109,7 @@ static int32 handleResends(SOCKET sock) if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) { /* This is the standard handshake case */ - psTraceDtls("Got HANDSHAKE_COMPLETE out of SentData\n"); + _psTrace("Got HANDSHAKE_COMPLETE out of SentData\n"); break; } /* SSL_REQUEST_SEND is handled by loop logic */ diff --git a/apps/ssl/Makefile b/apps/ssl/Makefile index 70a2a8a..539ce27 100644 --- a/apps/ssl/Makefile +++ b/apps/ssl/Makefile @@ -16,6 +16,21 @@ CLIENT_EXE:=client$(E) NET_EXE:=matrixnet$(E) EXE=$(SERVER_EXE) $(CLIENT_EXE) +SIMPLE_CLIENT_SRC:=simpleClient.c +SIMPLE_CLIENT_EXE:=simpleClient$(E) +SIMPLE_SERVER_SRC:=simpleServer.c +SIMPLE_SERVER_EXE:=simpleServer$(E) + +IA_CLIENT_SRC:=interactiveClient.c +IA_CLIENT_EXE:=interactiveClient$(E) + +SRC+=$(SIMPLE_CLIENT_SRC) +EXE+=$(SIMPLE_CLIENT_EXE) +SRC+=$(SIMPLE_SERVER_SRC) +EXE+=$(SIMPLE_SERVER_EXE) +SRC+=$(IA_CLIENT_SRC) +EXE+=$(IA_CLIENT_EXE) + #The Mac OS X Xcode project has a target name of 'server' or 'client' ifneq (,$(TARGET_NAME)) ifneq (,$(findstring server,$(TARGET_NAME))) @@ -47,6 +62,10 @@ STATIC:=\ $(MATRIXSSL_ROOT)/core/libcore_s.a \ $(STATIC_INTERNAL) +#ifdef USE_ROT_CRYPTO +STATIC+=$(LIBDRIVER_VAL_UP_PATH) +#endif + STATIC_CLIENT:=\ $(MATRIXSSL_ROOT)/apps/common/client_common_s.a @@ -67,6 +86,15 @@ $(SERVER_EXE): $(SERVER_SRC:.c=.o) $(STATIC) $(CLIENT_EXE): $(CLIENT_SRC:.c=.o) $(STATIC) $(STATIC_CLIENT) $(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS) +$(SIMPLE_CLIENT_EXE): $(SIMPLE_CLIENT_SRC:.c=.o) $(STATIC) + $(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS) + +$(IA_CLIENT_EXE): $(IA_CLIENT_SRC:.c=.o) $(STATIC) + $(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS) + +$(SIMPLE_SERVER_EXE): $(SIMPLE_SERVER_SRC:.c=.o) $(STATIC) + $(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS) + $(NET_EXE): $(NET_SRC:.c=.o) $(STATIC) $(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS) diff --git a/apps/ssl/client.c b/apps/ssl/client.c index 8f0275e..dbbb1aa 100644 --- a/apps/ssl/client.c +++ b/apps/ssl/client.c @@ -88,7 +88,7 @@ static int g_use_psk; # endif # define ALLOW_ANON_CONNECTIONS 0 -# define CRL_MAX_LENGTH 1048576 /* Maximum length for CRL: 1 megabyte. */ +# define CRL_MAX_LENGTH 2097152 /* Maximum length for CRL: 2 megabytes. */ /* #define REHANDSHAKE_TEST */ # ifdef REHANDSHAKE_TEST @@ -192,6 +192,10 @@ static void fetchSavedCRL(psX509Cert_t *potentialIssuers); static void sslstatsPrintTime(const struct g_sslstats* stats, int conn_count); static void addTimeDiff(int64 *t, psTime_t t1, psTime_t t2); +/* Not a public function, but needed for command-line backwards + compatibility. */ +extern int32_t psVerToFlag(psProtocolVersion_t ver); + /******************************************************************************/ /* Make a secure HTTP request to a defined IP and port @@ -341,7 +345,8 @@ static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid, while (supportedVersion) { supportedVersions[i] = atoi((char* )supportedVersion->item); - supportedVersions[i] = DIGIT_TO_VER(supportedVersions[i]); + supportedVersions[i] = matrixSslVersionFromMinorDigit( + supportedVersions[i]); supportedVersion = supportedVersion->next; i++; } @@ -366,7 +371,8 @@ static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid, } else if (g_version != 0) { - options.versionFlag = psVerToFlag(DIGIT_TO_VER(g_version)); + options.versionFlag = psVerToFlag(matrixSslVersionFromMinorDigit( + g_version)); } options.userPtr = keys; @@ -466,6 +472,7 @@ WRITE_MORE: } else { + psTraceBytes("sent", buf, len); /* Indicate that we've written > 0 bytes of data */ if ((rc = matrixSslSentData(ssl, transferred)) < 0) { @@ -480,7 +487,8 @@ WRITE_MORE: { Printf("TLS handshake complete.\n"); - if (USING_TLS_1_3(ssl) && sid != NULL && g_resumed > 0) + if ((matrixSslGetNegotiatedVersion(ssl) & v_tls_1_3_any) + && sid != NULL && g_resumed > 0) { /* Try to receive the server's NewSessionTicket. */ goto READ_MORE; @@ -515,7 +523,7 @@ READ_MORE: } if (g_trace) { - psTraceBytes("RECV", buf, transferred); + //psTraceBytes("RECV", buf, transferred); } /* If EOF, remote socket closed. But we haven't received the HTTP response so we consider it an error in the case of an HTTP client */ @@ -531,7 +539,7 @@ READ_MORE: # ifdef USE_EXT_CLIENT_CERT_KEY_LOADING if (rc == PS_PENDING && matrixSslNeedClientCert(ssl)) { - sslIdentity_t *id, *next; + sslKeys_t *newKeys; psTrace("Loading client cert and key in response to " \ "CertificateRequest\n"); @@ -542,25 +550,25 @@ READ_MORE: On a typical application the 'identity' keys would not be shared with initial NewClient call, and the ps-pending driven/callback driven mechanisms */ - for (id = ssl->keys->identity; id; id = next) - { - next = id->next; - if (id->cert) - psX509FreeCert(id->cert); - psClearPubKey(&id->privKey); - psFree(id, ssl->keys->pool); - } - ssl->keys->identity = NULL; + matrixSslDeleteKeys(matrixSslGetKeys(ssl)); - if (matrixSslLoadKeys(ssl->keys, - g_on_demand_cert_file, - g_on_demand_key_file, - NULL, NULL, NULL) < 0) + /* Load the "on-demand" keys. */ + rc = matrixSslNewKeys(&newKeys, NULL); + if (rc < 0) + { + psTrace("matrixSslNewKeys failed\n"); + exit(EXIT_FAILURE); + } + rc = matrixSslLoadKeys(newKeys, + g_on_demand_cert_file, + g_on_demand_key_file, + NULL, NULL, NULL); + if (rc < 0) { psTrace("matrixSslLoadKeys failed\n"); exit(EXIT_FAILURE); } - matrixSslSetClientIdentity(ssl, ssl->keys); + matrixSslSetClientIdentity(ssl, newKeys); (void)matrixSslClientCertUpdated(ssl); /* Retry now that we have the cert and the priv key. */ @@ -575,7 +583,7 @@ READ_MORE: # endif # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ - if (ssl->hsState == SSL_HS_DONE) + if (matrixSslHandshakeIsComplete(ssl)) { addTimeDiff(&stats->datatime, t1, t2); } @@ -586,7 +594,7 @@ READ_MORE: goto L_CLOSE_ERR; } psGetTime(&t2, NULL); - if (ssl->hsState == SSL_HS_DONE) + if (matrixSslHandshakeIsComplete(ssl)) { addTimeDiff(&stats->datatime, t1, t2); } @@ -764,7 +772,7 @@ PROCESS_MORE: /* The second byte is the description */ if (*buf == SSL_ALERT_LEVEL_FATAL) { - psTraceIntInfo("Fatal alert: %d, closing connection.\n", + psTraceInt("Fatal alert: %d, closing connection.\n", *(buf + 1)); goto L_CLOSE_ERR; } @@ -780,7 +788,7 @@ PROCESS_MORE: cp.parsebuflen = 0; return MATRIXSSL_SUCCESS; } - psTraceIntInfo("Warning alert: %d\n", *(buf + 1)); + psTraceInt("Warning alert: %d\n", *(buf + 1)); if ((rc = matrixSslProcessedData(ssl, &buf, (uint32 *) &len)) == 0) { /* No more data in buffer. Might as well read for more. */ @@ -859,7 +867,7 @@ static int32 httpWriteRequest(ssl_t *ssl) if (g_trace) { - psTraceStr("SEND: [%s]\n", (char *) buf); + //psTraceStr("SEND: [%s]\n", (char *) buf); } if (matrixSslEncodeWritebuf(ssl, Strlen((char *) buf)) < 0) { @@ -1223,8 +1231,8 @@ static int32 process_cmd_options(int32 argc, char **argv) /* Single version. */ version = atoi(optarg); if (!matrixSslTlsVersionRangeSupported( - DIGIT_TO_VER(version), - DIGIT_TO_VER(version))) + matrixSslVersionFromMinorDigit(version), + matrixSslVersionFromMinorDigit(version))) { Printf("Invalid version: %d\n", version); return -1; @@ -1276,8 +1284,10 @@ static int32 process_cmd_options(int32 argc, char **argv) optarg); return -1; } - g_min_version = DIGIT_TO_VER(atoi((char *)versionRangeList->item)); - g_max_version = DIGIT_TO_VER(atoi((char *)versionRangeList->next->item)); + g_min_version = matrixSslVersionFromMinorDigit( + atoi((char *)versionRangeList->item)); + g_max_version = matrixSslVersionFromMinorDigit( + atoi((char *)versionRangeList->next->item)); psFreeList(versionRangeList, NULL); if (!matrixSslTlsVersionRangeSupported( g_min_version, @@ -1444,10 +1454,6 @@ int32 main(int32 argc, char **argv) sslKeys_t *keys; sslSessionId_t *sid = NULL; struct g_sslstats stats; -# if defined(USE_HEADER_KEYS) && !defined(ID_RSA) - const unsigned char *key_buf; - int32 key_buf_len; -# endif /* USE_HEADER_KEYS && !ID_RSA */ # ifdef WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); @@ -1512,8 +1518,8 @@ int32 main(int32 argc, char **argv) rc = matrixSslLoadTls13Psk(keys, g_tls13_test_psk_256, sizeof(g_tls13_test_psk_256), - g_tls13_test_psk_id, - sizeof(g_tls13_test_psk_id), + g_tls13_test_psk_id_sha256, + sizeof(g_tls13_test_psk_id_sha256), NULL); if (rc < 0) { @@ -1527,7 +1533,9 @@ int32 main(int32 argc, char **argv) /* One initialization step that can be taken is to run through the CA files and see if any CRL URL distribution points are present. Fetch the CRL and load into the cache if found */ - fetchParseAndAuthCRLfromCert(NULL, keys->CAcerts, keys->CAcerts); + fetchParseAndAuthCRLfromCert(NULL, + sslKeysGetCACerts(keys), + sslKeysGetCACerts(keys)); # endif Memset(&stats, 0x0, sizeof(struct g_sslstats)); @@ -1555,7 +1563,7 @@ int32 main(int32 argc, char **argv) will be available on this next connection attempt. */ if (g_crlDistURLs[0][0] == 'h') /* assumption is "http" */ { - fetchSavedCRL(keys->CAcerts); + fetchSavedCRL(sslKeysGetCACerts(keys)); } # endif # endif @@ -1810,7 +1818,7 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert) if (alert == SSL_ALERT_CERTIFICATE_UNKNOWN) { psTraceStr("ERROR: %s not found in cert subject names\n", - ssl->expectedName); + matrixSslGetExpectedName(ssl)); } if (alert == SSL_ALERT_CERTIFICATE_EXPIRED) @@ -1910,7 +1918,9 @@ RETRY_CRL_TEST_ONCE: so it is correct that the server cert will look for the first instance of CHECK_EXPECTED and pass that as the start of chain to work upon */ - fetchParseAndAuthCRLfromCert(NULL, next, ssl->keys->CAcerts); + fetchParseAndAuthCRLfromCert(NULL, + next, + sslKeysGetCACerts(matrixSslGetKeys(ssl))); /* If all went well, every cert in the server chain will have an updated status */ retryOnce++; diff --git a/apps/ssl/interactiveClient.c b/apps/ssl/interactiveClient.c new file mode 100644 index 0000000..9aa60ab --- /dev/null +++ b/apps/ssl/interactiveClient.c @@ -0,0 +1,1364 @@ +/** + * @file interactiveClient.c + * @version $Format:%h%d$ + * + * Interactive client-side test tool. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "matrixssl/matrixsslApi.h" +#include "osdep.h" + +# ifdef USE_CLIENT_SIDE_SSL + +# if defined(USE_TLS_1_2) && defined(USE_SECP256R1) && defined(USE_SHA256) && defined(USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) && defined(USE_IDENTITY_CERTIFICATES) + +# include +# include +# include +# include +# include + +/* Key material. */ +# include "testkeys/EC/256_EC.h" +# include "testkeys/EC/256_EC_KEY.h" +# include "testkeys/EC/256_EC_CA.h" +# include "testkeys/RSA/2048_RSA.h" +# include "testkeys/RSA/2048_RSA_KEY.h" +# include "testkeys/RSA/3072_RSA.h" +# include "testkeys/RSA/3072_RSA_KEY.h" +# include "testkeys/RSA/ALL_RSA_CAS.h" +# include "testkeys/EC/ALL_EC_CAS.h" +# include "testkeys/PSK/tls13_psk.h" + +# define SERVER_IP_ADDRESS "127.0.0.1" +# define SERVER_PORT 4433 + +/* Do we expect the server to the first piece of app data? */ +static int g_server_sends_first; +/* Use matrixSslEncodeToOutdata for encoding small app data? */ +static int g_encode_to_outdata; +/* Already received MATRIXSSL_HANDSHAKE_COMPLETE? */ +static int g_handshake_complete; +/* Skip server authentication entirely? */ +static psBool_t g_skip_server_auth; + +static size_t leftNBytes; +static size_t sentNBytes; + +/* HTTP GET request header. */ +static unsigned char g_httpRequestHdr[] = "GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n" + "Accept: */*\r\n" + "Content-Length: 0\r\n" + "\r\n"; + +/* Certificate callback. See section 6 in the API manual for details. + In this test, we do no extra checks of our own; we simply accept + the result of MatrixSSL's internal certificate validation. */ +static int32_t certCb(ssl_t *ssl, psX509Cert_t *cert, int32_t alert) +{ + if (g_skip_server_auth) + { + return SSL_ALLOW_ANON_CONNECTION; + } + else + { + return alert; + } +} + +/* Returns a line of user input (without the newline character), + or < 0 on error. The returned string may be truncated if it + did not fit into buf. */ +int get_user_input(char *buf, int buf_len) +{ + char *s, *p; + char c; + + s = fgets(buf, buf_len, stdin); + if (s == NULL) + { + return PS_FAILURE; + } + + p = strchr(buf, '\n'); + if (p) + { + *p = '\0'; + } + else + { + /* Flush stdin up to newline or EOF. */ + c = getchar(); + while (c != '\n' && !feof(stdin) && !ferror(stdin)) + { + c = getchar(); + } + } + + //printf("Got: %s (len: %zu)\n", buf, strlen(buf)); + + return PS_SUCCESS; +} + +int get_user_input_char(char *c, char defaultChoice) +{ + char buf[2] = {0}; + size_t buf_len = sizeof(buf); + int rc; + + rc = get_user_input(buf, buf_len); + if (rc < 0) + { + return rc; + } + + if (Strlen(buf) == 0) + { + *c = defaultChoice; + } + else + { + *c = buf[0]; + } + + return PS_SUCCESS; +} + +static int32_t getAppDataFromUser(ssl_t *ssl, + unsigned char *data, + size_t *dataLen) +{ + int rc; + char buf[1024] = {0}; + size_t buf_len = sizeof(buf); + size_t max_len; + + max_len = buf_len; + if (*dataLen < buf_len && *dataLen < INT_MAX) + { + max_len = *dataLen; + } + + rc = get_user_input(buf, (int)max_len); + if (rc < 0) + { + printf("Failed to get user input\n"); + return PS_FAILURE; + } + + Memcpy(data, buf, Strlen(buf) + 1); + *dataLen = Strlen(buf) + 1; + + return PS_SUCCESS; +} + +/* + Ask the for app data to send over the encrypted connection, + or for some other action. + Return value: + < 0 on error, + PS_SUCCESS for nominal connection closure + MATRIXSSL_REQUEST_SEND to send app data. +*/ +static int32_t askSendAppData(ssl_t *ssl) +{ + int32_t rc; + unsigned char *buf; + unsigned char data[1024] = {0}; + size_t dataLen = sizeof(data); + size_t sendNBytes; + static unsigned char *fileData = NULL; + unsigned char *pData; + const char *s; + + if (leftNBytes > 0) + { + pData = fileData; + goto continue_sending; + } + + printf("You: "); + rc = getAppDataFromUser(ssl, data, &dataLen); + if (rc < 0) + { + return rc; + } + + if (data[0] == ':') + { + /* Handle commands. */ + + /* Handle :quit, :exit and :q */ + s = (char*)&data[1]; + if (!Strncmp(s, "quit", strlen("quit")) + || !Strncmp(s, "exit", strlen("exit")) + || (dataLen == 2 && data[1] == 'q')) + { + rc = matrixSslEncodeClosureAlert(ssl); + (void)rc; + return PS_SUCCESS; + } + if (!Strncmp(s, "file", strlen("file"))) + { +# ifdef MATRIX_USE_FILE_SYSTEM + printf("Enter file name: "); + dataLen = sizeof(data); + rc = getAppDataFromUser(ssl, data, &dataLen); + if (rc < 0) + { + goto out_fail; + } + rc = psGetFileBuf(NULL, (char*)data, &fileData, &dataLen); + if (rc < 0) + { + printf("Unable to open file\n"); + sprintf((char*)data, "%s", "[I tried to send a file, but failed]"); + } +# else + printf("Need MATRIX_USE_FILE_SYSTEM for this\n"); + rc = PS_UNSUPPORTED_FAIL; + goto out_fail; +# endif /* MATRIX_USE_FILE_SYSTEM */ + } + if (!Strncmp(s, "url", strlen("url"))) + { + unsigned char url[sizeof(data)] = {0}; + int n; + + printf("Enter URL to GET: "); + dataLen = sizeof(url); + rc = getAppDataFromUser(ssl, url, &dataLen); + if (rc < 0) + { + goto out_fail; + } + n = Snprintf((char*)data, + sizeof(data), + (char*)g_httpRequestHdr, + (char*)url, + "localhost"); + dataLen = n + 1; + printf("Sending: %s (len: %zu)\n", data, dataLen); + } + } + + if (fileData != NULL) + { + pData = fileData; + } + else + { + pData = data; + } + + leftNBytes = dataLen; + sentNBytes = 0; + +continue_sending: + /* Get pointer to the internal plaintext buffer and fill + it with the plaintext data. The returned buffer may + be smaller, in which case we'll come back here to + continue on next call. */ + if (g_encode_to_outdata && leftNBytes < 16384) + { + rc = matrixSslEncodeToOutdata(ssl, pData, leftNBytes); + if (rc < 0) + { + printf("matrixSslEncodeToOutdata failed: %d\n", rc); + goto out_fail; + } + leftNBytes = 0; + } + else + { + rc = matrixSslGetWritebuf(ssl, &buf, leftNBytes); + if (rc < 0) + { + rc = PS_FAILURE; + goto out_fail; + } + + if (rc < leftNBytes) + { + sendNBytes = rc; + } + else + { + sendNBytes = leftNBytes; + } + + memcpy(buf, pData, sendNBytes); + sentNBytes += sendNBytes; + leftNBytes -= sendNBytes; + + printf("Sent %zu/%zu bytes\n", sentNBytes, sentNBytes + leftNBytes); + + /* Encrypt. */ + rc = matrixSslEncodeWritebuf(ssl, sendNBytes); + if (rc < 0) + { + rc = PS_FAILURE; + goto out_fail; + } + } + + /* Ask the main loop to send it over the wire. */ + rc = MATRIXSSL_REQUEST_SEND; + +out_fail: + if (fileData != NULL) + { + if (leftNBytes == 0) + { + psFree(fileData, NULL); + fileData = NULL; + } + } + return rc; +} + +psRes_t getUserProtocolVersion(psProtocolVersion_t *verOut) +{ + const char *proto_ver_prompt = + "Select protocol version to use:\n" \ + "(4) TLS 1.3 (default)\n" \ + "(3) TLS 1.2\n" \ + "(2) TLS 1.1\n" \ + "(1) TLS 1.0\n"; + char c; + psProtocolVersion_t v; + int got_it = 0; + int rc; + + printf("%s", proto_ver_prompt); + + while (got_it == 0) + { + rc = get_user_input_char(&c, '4'); + if (rc < 0) + { + printf("getUserProtocolVersion failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '4': + v = v_tls_1_3; + break; + case '3': + v = v_tls_1_2; + break; + case '2': + v = v_tls_1_1; + break; + case '1': + v = v_tls_1_0; + break; + case 'q': + return PS_FAILURE; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + *verOut = v; + + return PS_SUCCESS; +} + +psRes_t getUserKeyPair(const unsigned char **cert, + int32_t *certLen, + const unsigned char **key, + int32_t *keyLen, + int32_t *keyType, + int32_t *pskLen) +{ + const char *key_prompt = + "Select authentication key pair to use:\n" \ + "(1) P-256 ECDSA (default)\n" \ + "(2) 2048-bit RSA\n" \ + "(3) 3072-bit RSA\n" \ + "(4) PSK (32 bytes)\n" \ + "(5) PSK (48 bytes)\n"; + char c; + int got_it = 0; + int rc; + + /* Default keys. */ + *cert = EC256; + *certLen = EC256_SIZE; + *key = EC256KEY; + *keyLen = EC256KEY_SIZE; + *keyType = PS_ECC; + *pskLen = 0; + + printf("%s", key_prompt); + + while (got_it == 0) + { + rc = get_user_input_char(&c, '1'); + if (rc < 0) + { + printf("getUserKeyPair failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '1': + /* Use defaults from above. */ + break; + case '2': + *cert = RSA2048; + *certLen = RSA2048_SIZE; + *key = RSA2048KEY; + *keyLen = RSA2048KEY_SIZE; + *keyType = PS_RSA; + break; + case '3': + *cert = RSA3072; + *certLen = RSA3072_SIZE; + *key = RSA3072KEY; + *keyLen = RSA3072KEY_SIZE; + *keyType = PS_RSA; + break; + case '4': + *pskLen = 32; + /* Load default keys in addition to the PSK. */ + break; + case '5': + *pskLen = 48; + /* Load default keys in addition to the PSK. */ + break; + case 'q': + return PS_FAILURE; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + return PS_SUCCESS; +} + +int load_keys(sslKeys_t *keys) +{ + const unsigned char *key, *cert; + int32_t keyLen, certLen; + int32_t keyType; + const unsigned char *psk; + const unsigned char *psk_id; + psSize_t psk_id_len; + int32_t pskLen; + int rc; + matrixSslLoadKeysOpts_t keyOpts; + + rc = getUserKeyPair(&key, &keyLen, &cert, &certLen, &keyType, &pskLen); + if (rc < 0) + { + return rc; + } + + Memset(&keyOpts, 0, sizeof(keyOpts)); + keyOpts.key_type = keyType; + +# ifdef USE_TLS_1_3 + if (pskLen > 0) + { + if (pskLen == 32) + { + psk = g_tls13_test_psk_256; + psk_id = g_tls13_test_psk_id_sha256; + psk_id_len = sizeof(g_tls13_test_psk_id_sha256); + } + else if (pskLen == 48) + { + psk = g_tls13_test_psk_384; + psk_id = g_tls13_test_psk_id_sha384; + psk_id_len = sizeof(g_tls13_test_psk_id_sha384); + } + else + { + printf("Invalid PSK length\n"); + return EXIT_FAILURE; + } + rc = matrixSslLoadTls13Psk( + keys, + psk, + pskLen, + psk_id, + psk_id_len, + NULL); + if (rc < 0) + { + printf("matrixSslLoadTls13Psk failed\n"); + return EXIT_FAILURE; + } + } +# endif + + rc = matrixSslLoadKeysMem( + keys, + key, + keyLen, + cert, + certLen, + RSACAS, + sizeof(RSACAS), + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMem failed for key pair: %d\n", rc); + return EXIT_FAILURE; + } + + if (keyType == PS_ECC) + { + rc = matrixSslLoadKeysMem( + keys, + NULL, + 0, + NULL, + 0, + ECCAS, + sizeof(ECCAS), + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMem failed for ECC CAs: %d\n", rc); + return EXIT_FAILURE; + } + } + + return PS_SUCCESS; +} + +psRes_t getUserFirstSender(void) +{ + const char *get_first_sender_prompt = + "Who will send app data first?\n" \ + "(1) client (default)\n" \ + "(2) server\n"; + int rc; + char c; + int got_it = 0; + + printf("%s", get_first_sender_prompt); + while (got_it == 0) + { + rc = get_user_input_char(&c, '1'); + if (rc < 0) + { + printf("getUserFirstSender failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '1': + g_server_sends_first = 0; + break; + case '2': + g_server_sends_first = 1; + break; + case 'q': + return PS_FAILURE; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + return PS_SUCCESS; +} + +psRes_t getEncodingFunc(void) +{ + const char *get_encoding_func_prompt = + "Use matrixSslEncodeToOutdata for small <16KB application data?\n" \ + "(1) no (default)\n" \ + "(2) yes\n"; + int rc; + char c; + int got_it = 0; + + printf("%s", get_encoding_func_prompt); + while (got_it == 0) + { + rc = get_user_input_char(&c, '1'); + if (rc < 0) + { + printf("getUserFirstSender failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '1': + g_encode_to_outdata = 0; + break; + case '2': + g_encode_to_outdata = 1; + break; + case 'q': + return PS_FAILURE; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + return PS_SUCCESS; +} + +psRes_t getUserSigAlgs(uint16_t *sigAlgs, psSize_t *numSigAlgs) +{ + const char *sig_algs_prompt = + "Signature algorithms to use:\n" \ + "(1) sigalg_ecdsa_secp256r1_sha256 (default)\n" \ + "(2) sigalg_rsa_pss_rsae_sha256\n" \ + "(3) sigalg_rsa_pkcs1_sha256\n"; + + int rc; + char c; + int got_it = 0; + psSize_t i = 0; + + printf("%s", sig_algs_prompt); + while (got_it == 0) + { + rc = get_user_input_char(&c, '1'); + if (rc < 0) + { + printf("getUserSigAlgs failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '1': + sigAlgs[i++] = sigalg_ecdsa_secp256r1_sha256; + break; + case '2': + sigAlgs[i++] = sigalg_rsa_pss_rsae_sha256; + break; + case '3': + sigAlgs[i++] = sigalg_rsa_pkcs1_sha256; + break; + case 'q': + return PS_FAILURE; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + *numSigAlgs = i; + + return PS_SUCCESS; +} + +psRes_t getUserCiphersuites(psCipher16_t *ciphersuites, + psSize_t *numCiphersuites) +{ + static const char *ciphersuites_prompt = + "Ciphersuite to use:\n" \ + "(1) TLS_AES_128_GCM_SHA256 (default)\n" \ + "(2) TLS_AES_256_GCM_SHA384\n" \ + "(3) TLS_CHACHA20_POLY1305_SHA256\n" \ + "(4) TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\n" \ + "(5) TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n" \ + "(6) TLS_RSA_WITH_AES_128_GCM_SHA256\n" \ + "(7) All TLS 1.3 suites (prefer SHA256)\n" \ + "(8) All TLS 1.3 suites (prefer SHA384)\n"; + int rc; + char c; + int got_it = 0; + psSize_t i = 0; + + printf("%s", ciphersuites_prompt); + while (got_it == 0) + { + rc = get_user_input_char(&c, '1'); + if (rc < 0) + { + printf("getUserCiphersuites failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '1': + ciphersuites[i++] = TLS_AES_128_GCM_SHA256; + break; + case '2': + ciphersuites[i++] = TLS_AES_256_GCM_SHA384; + break; + case '3': + ciphersuites[i++] = TLS_CHACHA20_POLY1305_SHA256; + break; + case '4': + ciphersuites[i++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; + break; + case '5': + ciphersuites[i++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; + break; + case '6': + ciphersuites[i++] = TLS_RSA_WITH_AES_128_GCM_SHA256; + break; + case '7': + ciphersuites[i++] = TLS_AES_128_GCM_SHA256; + ciphersuites[i++] = TLS_AES_256_GCM_SHA384; + ciphersuites[i++] = TLS_CHACHA20_POLY1305_SHA256; + break; + case '8': + ciphersuites[i++] = TLS_AES_256_GCM_SHA384; + ciphersuites[i++] = TLS_AES_128_GCM_SHA256; + ciphersuites[i++] = TLS_CHACHA20_POLY1305_SHA256; + break; + case 'q': + return PS_FAILURE; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + *numCiphersuites = i; + + return PS_SUCCESS; +} + +psRes_t getMaximumFragmentLength(short *maxFragLen) +{ + const char *max_frag_len_prompt = + "Maximum fragment length\n" \ + "(1) none (default)\n" \ + "(2) 512\n" \ + "(3) 1024\n" \ + "(4) 2048\n" \ + "(5) 4096\n"; + int rc; + char c; + int got_it = 0; + + printf("%s", max_frag_len_prompt); + while (got_it == 0) + { + rc = get_user_input_char(&c, '1'); + if (rc < 0) + { + printf("getMaximumFragmentLength failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '1': + *maxFragLen = 0; + break; + case '2': + *maxFragLen = 512; + break; + case '3': + *maxFragLen = 1024; + break; + case '4': + *maxFragLen = 2048; + break; + case '5': + *maxFragLen = 4096; + break; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + return PS_SUCCESS; +} + +psRes_t getServerAddress(char *addr_out, int *addr_out_len) +{ + const char *server_address_prompt = + "Server IP address (default 127.0.0.1):\n"; + char addr[40]; + int addr_len = (int)sizeof(addr); + const char *addr_default = "127.0.0.1"; + int rc; + + printf("%s", server_address_prompt); + rc = get_user_input(addr, addr_len); + if (rc < 0) + { + return PS_FAILURE; + } + + if (Strlen(addr) == 0) + { + Strncpy(addr_out, addr_default, 39); + } + else + { + Strncpy(addr_out, addr, 39); + } + + *addr_out_len = strlen(addr); + + return PS_SUCCESS; +} + +psRes_t getServerPort(int *port_out) +{ + const char *server_port_prompt = + "Server port (default: 4433)\n"; + char buf[6]; + int buf_len = sizeof(buf); + long int port; + char *end; + int got_it = 0; + int rc; + + printf("%s", server_port_prompt); + + while (got_it == 0) + { + rc = get_user_input(buf, buf_len); + if (rc < 0) + { + return PS_FAILURE; + } + got_it = 1; + port = Strtol(buf, &end, 10); + if (port < 0 || port > 65536) + { + printf("Invalid port\n"); + got_it = 0; + } + if (buf == end) + { + port = 4433; + } + } + + *port_out = port; + return PS_SUCCESS; +} + +psRes_t getServerName( + char *name_out, + int name_out_len, + char *ip_addr) +{ + const char *server_name_prompt_fmt = + "Server name (default: %s)\n"; + char server_name_prompt[256]; + char buf[256]; + int buf_len = sizeof(buf); + char *name; + int got_it = 0; + int rc; + + /* Default name = previously selected IP address. */ + snprintf(server_name_prompt, + 256, + server_name_prompt_fmt, + ip_addr); + printf("%s", server_name_prompt); + + while (got_it == 0) + { + rc = get_user_input(buf, buf_len); + if (rc < 0) + { + return PS_FAILURE; + } + got_it = 1; + } + + if (Strlen(buf) == 0) + { + if (name_out_len < Strlen(ip_addr)) + { + printf("Default server name won't fit into output buffer\n"); + return PS_FAILURE; + } + Strncpy(name_out, ip_addr, name_out_len - 1); + } + else + { + Strncpy(name_out, buf, buf_len - 1); + } + + return PS_SUCCESS; +} + +psRes_t getAllowAnon(psBool_t *allow) +{ + const char *allow_anon_prompt = + "Skip server authentication?\n" \ + "(1) no (default)\n" \ + "(2) yes\n"; + int rc; + char c; + int got_it = 0; + + printf("%s", allow_anon_prompt); + while (got_it == 0) + { + rc = get_user_input_char(&c, '1'); + if (rc < 0) + { + printf("getAllowAnon failed\n"); + return PS_FAILURE; + } + got_it = 1; + switch (c) + { + case '1': + *allow = PS_FALSE; + break; + case '2': + *allow = PS_TRUE; + break; + default: + printf("Invalid choice: %c\n", c); + got_it = 0; + } + } + + return PS_SUCCESS; +} + +int main(int argc, char **argv) +{ + uint16_t sigAlgs[16]; + psSize_t numSigAlgs; + psProtocolVersion_t versions[1]; + psCipher16_t ciphersuites[1]; + psSize_t numCiphersuites; + char serverAddress[39]; + char serverName[256] = { '\0' }; + int serverNameLen = sizeof(serverName); + int serverAddressLen; + int serverPort; + unsigned char *sniExtData; + int32_t sniExtDataLen; + tlsExtension_t *sniExt; + sslSessOpts_t opts; + sslKeys_t *keys; + int32_t rc; + uint32_t len; + ssl_t *ssl = NULL; + unsigned char *buf; + ssize_t nrecv, nsent; + int fd = -1; + struct sockaddr_in addr; + + rc = matrixSslOpen(); + if (rc < 0) + { + return EXIT_FAILURE; + } + + Memset(&opts, 0, sizeof(opts)); + + rc = getUserProtocolVersion(&versions[0]); + if (rc < 0) + { + return EXIT_FAILURE; + } + rc = matrixSslSessOptsSetClientTlsVersions( + &opts, + versions, + 1); + if (rc < 0) + { + printf("matrixSslSessOptsSetClientTlsVersions failed: %d\n", rc); + return EXIT_FAILURE; + } + + rc = matrixSslNewKeys(&keys, NULL); + if (rc < 0) + { + return EXIT_FAILURE; + } + + rc = load_keys(keys); + if (rc < 0) + { + matrixSslDeleteKeys(keys); + return EXIT_FAILURE; + } + + /* Set P-256 as the supported ECC curve for signatures and key exchange. */ + opts.ecFlags = IS_SECP256R1; + + rc = getUserSigAlgs(sigAlgs, &numSigAlgs); + if (rc < 0) + { + goto out_fail; + } + rc = matrixSslSessOptsSetSigAlgs( + &opts, + sigAlgs, + numSigAlgs); + if (rc < 0) + { + printf("matrixSslSessOptsSetSigAlgs failed: %d\n", rc); + goto out_fail; + } + + rc = getUserCiphersuites(ciphersuites, &numCiphersuites); + if (rc < 0) + { + goto out_fail; + } + + rc = getMaximumFragmentLength(&opts.maxFragLen); + if (rc < 0) + { + goto out_fail; + } + + rc = getServerAddress(serverAddress, &serverAddressLen); + if (rc < 0) + { + goto out_fail; + } + + rc = getServerPort(&serverPort); + if (rc < 0) + { + goto out_fail; + } + + rc = getServerName(serverName, sizeof(serverName), serverAddress); + if (rc < 0) + { + goto out_fail; + } + + matrixSslNewHelloExtension(&sniExt, NULL); + matrixSslCreateSNIext( + NULL, + (unsigned char*)serverName, + (uint32_t)Strlen(serverName), + &sniExtData, + &sniExtDataLen); + matrixSslLoadHelloExtension( + sniExt, + sniExtData, + sniExtDataLen, + EXT_SNI); + + /* Create a new session and the ClientHello message. */ + rc = matrixSslNewClientSession( + &ssl, + keys, + NULL, + ciphersuites, + numCiphersuites, + certCb, + serverName, + sniExt, + NULL, + &opts); + if (rc < 0) + { + printf("matrixSslNewClientSession failed: %d\n", rc); + goto out_fail; + } + + matrixSslDeleteHelloExtension(sniExt); + psFree(sniExtData, NULL); + + rc = getUserFirstSender(); + if (rc < 0) + { + goto out_fail; + } + + rc = getEncodingFunc(); + if (rc < 0) + { + goto out_fail; + } + + rc = getAllowAnon(&g_skip_server_auth); + if (rc < 0) + { + goto out_fail; + } + + /* Open the TCP connection. */ + Memset((char *) &addr, 0x0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons((short) serverPort); + addr.sin_addr.s_addr = inet_addr(serverAddress); + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + { + printf("socket failed: %d\n", fd); + goto out_fail; + } + rc = connect(fd, (struct sockaddr *) &addr, sizeof(addr)); + if (rc < 0) + { + close(fd); + printf("connect failed: %d\n", rc); + goto out_fail; + } + +WRITE_MORE: + /* Get pointer to the output data to send. */ + rc = matrixSslGetOutdata(ssl, &buf); + while (rc > 0) + { + len = rc; + + /* Send it over the wire. */ + nsent = send(fd, buf, len, 0); + if (nsent <= 0) + { + printf("send() failed\n"); + goto out_fail; + } + + /* Inform the TLS library how much we managed to send. + Return code will tell us of what to do next. */ + rc = matrixSslSentData(ssl, nsent); + if (rc < 0) + { + printf("matrixSslSentData failed: %d\n", rc); + goto out_fail; + } + else if (rc == MATRIXSSL_REQUEST_CLOSE) + { + printf("Closing connection\n"); + goto out_ok; + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + printf("Handshake complete\n"); + g_handshake_complete = 1; + + if (g_server_sends_first) + { + printf("Expecting server to transmit first\n"); + goto READ_MORE; + } + + /* Send app data over the encrypted connection. */ +get_more_user_data: + rc = askSendAppData(ssl); + if (rc == PS_SUCCESS) + { + goto out_ok; + } + else if (rc < 0) + { + goto out_fail; + } + goto WRITE_MORE; + } + /* rc == PS_SUCCESS. */ + + /* More data to send? */ + if (leftNBytes > 0) + { + goto get_more_user_data; + } + + rc = matrixSslGetOutdata(ssl, &buf); + } + +READ_MORE: + /* Get pointer to buffer where incoming data should be read into. */ + rc = matrixSslGetReadbuf(ssl, &buf); + if (rc < 0) + { + goto out_fail; + } + len = rc; + + /* Read data from the wire. */ + nrecv = recv(fd, buf, len, 0); + if (nrecv < 0) + { + goto out_fail; + } + + /* Ask the TLS library to process the data we read. + Return code will tell us what to do next. */ + rc = matrixSslReceivedData( + ssl, + nrecv, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + else if (rc == MATRIXSSL_RECEIVED_ALERT) + { + printf("Exiting on alert\n"); + goto out_fail; + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + if (g_handshake_complete) + { + /* This can happen when we receive further handshake messages + from the server after successful completion of the + handshake. In TLS 1.3, this occurs with NewSessionTicket + messages and post-handshake client authentication. + We already given whoever should transmit first a chance. + So now we try again to get app data from the server. */ + goto READ_MORE; + } + + printf("Handshake complete\n"); + g_handshake_complete = 1; + + if (g_server_sends_first) + { + printf("Expecting server to transmit first\n"); + goto READ_MORE; + } + + /* Send app data over the encrypted connection. */ + rc = askSendAppData(ssl); + if (rc == PS_SUCCESS) + { + goto out_ok; + } + else if (rc < 0) + { + goto out_fail; + } + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_SEND) + { + /* Handshake messages or an alert have been encoded. + These need to be sent over the wire. */ + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_RECV) + { + /* Handshake still in progress. Need more messages + from the peer. */ + goto READ_MORE; + } + else if (rc == MATRIXSSL_APP_DATA) + { + char *tmp; + + /* We received encrypted application data from the peer. + Just print it out here. */ + tmp = malloc(len+1); + if (tmp == NULL) + { + goto out_fail; + } + Memcpy(tmp, buf, len); + tmp[len] = '\0'; + + printf("Server: %s", tmp); + if (strchr(tmp, '\n') == NULL) + { + printf("\n"); + } + free(tmp); + + /* Inform the TLS library that we "processed" the data. */ + rc = matrixSslProcessedData( + ssl, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + + /* This test ends after successful reception of encrypted + app data from the peer. */ + rc = askSendAppData(ssl); + if (rc == PS_SUCCESS) + { + goto out_ok; + } + else if (rc < 0) + { + goto out_fail; + } + goto WRITE_MORE; + } + +out_ok: + rc = PS_SUCCESS; + +out_fail: + matrixSslDeleteSession(ssl); + matrixSslDeleteKeys(keys); + matrixSslClose(); + close(fd); + + if (rc == PS_SUCCESS) + { + return EXIT_SUCCESS; + } + else + { + return EXIT_FAILURE; + } +} + +# else +int main(int argc, char **argv) +{ + _psTrace("This test requires USE_TLS_1_2, USE_SECP256R1, " \ + "USE_SHA256 and USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.\n"); + return 1; +} +# endif /* USE_TLS_1_2 && USE_SECP256R1 && USE_SHA256 && USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 && USE_IDENTITY_CERTIFICATES */ +# else +int main(int argc, char **argv) +{ + _psTrace("This test requires USE_TLS_1_2, USE_SECP256R1, " \ + "USE_SHA256, USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 " \ + "and USE_IDENTITY_CERTIFICATES.\n"); + return 1; +} +# endif /* USE_CLIENT_SIDE_SSL */ diff --git a/apps/ssl/net.c b/apps/ssl/net.c index fad32d1..dcccace 100644 --- a/apps/ssl/net.c +++ b/apps/ssl/net.c @@ -48,7 +48,7 @@ # define DEBUGF(...) do {} while (0) #endif -#if defined(USE_PS_NETWORKING) && !defined(USE_ONLY_PSK_CIPHER_SUITE) +#if defined(USE_PS_NETWORKING) && !defined(USE_ONLY_PSK_CIPHER_SUITE) && defined(MATRIX_USE_FILE_SYSTEM) /* The flags used by this program for TLS versions. */ # define FLAG_TLS_1_0 (1 << 10) @@ -944,6 +944,10 @@ int32 main(int32 argc, char **argv) Printf("USE_PS_NETWORKING must be enabled at build" " time to run this application\n"); # endif +# ifndef MATRIX_USE_FILE_SYSTEM + Printf("MATRIX_USE_FILE_SYSTEM must be enabled at build" + " time to run this application\n"); +# endif # ifdef USE_ONLY_PSK_CIPHER_SUITE Printf("This application is not compatible with" " USE_ONLY_PSK_CIPHER_SUITE.\n"); diff --git a/apps/ssl/server.c b/apps/ssl/server.c index 059b515..b9bff2d 100644 --- a/apps/ssl/server.c +++ b/apps/ssl/server.c @@ -265,7 +265,7 @@ void SNIcallback(void *ssl, char *hostname, int32 hostnameLen, } else { - *newKeys = lssl->keys; + *newKeys = matrixSslGetKeys(lssl); } Free(str); @@ -285,7 +285,8 @@ int32 setProtocolVersions(sslSessOpts_t *options) while (supportedVersion) { supportedVersions[i] = atoi((char* )supportedVersion->item); - supportedVersions[i] = DIGIT_TO_VER(supportedVersions[i]); + supportedVersions[i] = matrixSslVersionFromMinorDigit( + supportedVersions[i]); supportedVersion = supportedVersion->next; i++; } @@ -888,7 +889,7 @@ PROCESS_MORE: /* The second byte is the description */ if (*buf == SSL_ALERT_LEVEL_FATAL) { - psTraceIntInfo("Fatal alert: %d, closing connection.\n", + psTraceInt("Fatal alert: %d, closing connection.\n", *(buf + 1)); closeConn(cp, PS_PROTOCOL_FAIL); continue; /* Next connection */ @@ -899,7 +900,7 @@ PROCESS_MORE: closeConn(cp, PS_SUCCESS); continue; /* Next connection */ } - psTraceIntInfo("Warning alert: %d\n", *(buf + 1)); + psTraceInt("Warning alert: %d\n", *(buf + 1)); if ((rc = matrixSslProcessedData(cp->ssl, &buf, (uint32 *) &len)) == 0) { /* No more data in buffer. Might as well read for more. */ @@ -993,7 +994,7 @@ static int32 httpWriteResponse(httpConn_t *cp) } # ifdef USE_TLS_1_3 - if (ssl->flags & SSL_FLAGS_TLS_1_3_NEGOTIATED) + if (matrixSslGetNegotiatedVersion(ssl) & v_tls_1_3_any) { rc = sendHtmlResponseTls13(ssl); } @@ -1337,7 +1338,7 @@ static int32 process_cmd_options(int32 argc, char **argv) case 'v': /* Single version. */ - version = DIGIT_TO_VER(atoi(optarg)); + version = matrixSslVersionFromMinorDigit(atoi(optarg)); if (!matrixSslTlsVersionRangeSupported(version, version)) { @@ -1356,8 +1357,10 @@ static int32 process_cmd_options(int32 argc, char **argv) psFreeList(versionRangeList, NULL); return -1; } - g_min_version = DIGIT_TO_VER(atoi((char *)versionRangeList->item)); - g_max_version = DIGIT_TO_VER(atoi((char *)versionRangeList->next->item)); + g_min_version = matrixSslVersionFromMinorDigit( + atoi((char *)versionRangeList->item)); + g_max_version = matrixSslVersionFromMinorDigit( + atoi((char *)versionRangeList->next->item)); psFreeList(versionRangeList, NULL); if (!matrixSslTlsVersionRangeSupported(g_min_version, g_max_version)) @@ -1557,18 +1560,32 @@ int32 main(int32 argc, char **argv) # ifdef USE_TLS_1_3 if (g_use_psk) { - /* Load the TLS 1.3 test PSK. */ + /* Load the TLS 1.3 test SHA-256 based PSK. */ rc = matrixSslLoadTls13Psk(keys, g_tls13_test_psk_256, sizeof(g_tls13_test_psk_256), - g_tls13_test_psk_id, - sizeof(g_tls13_test_psk_id), + g_tls13_test_psk_id_sha256, + sizeof(g_tls13_test_psk_id_sha256), NULL); if (rc < 0) { psTrace("Unable to load PSK keys.\n"); return rc; } +# ifdef USE_TLS_AES_256_GCM_SHA384 + /* Add the SHA-384 PSK. */ + rc = matrixSslLoadTls13Psk(keys, + g_tls13_test_psk_384, + sizeof(g_tls13_test_psk_384), + g_tls13_test_psk_id_sha384, + sizeof(g_tls13_test_psk_id_sha384), + NULL); + if (rc < 0) + { + psTrace("Unable to load PSK keys.\n"); + return rc; + } +# endif } # endif diff --git a/apps/ssl/simpleClient.c b/apps/ssl/simpleClient.c new file mode 100644 index 0000000..d7ad91e --- /dev/null +++ b/apps/ssl/simpleClient.c @@ -0,0 +1,669 @@ +/** + * @file simpleClient.c + * @version $Format:%h%d$ + * + * Simple MatrixSSL blocking client example. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "matrixssl/matrixsslApi.h" + +# if defined(USE_CLIENT_SIDE_SSL) && defined(USE_TLS_1_2) && (defined(USE_SECP256R1) || defined(USE_RSA)) && (defined(USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) || defined(USE_TLS_RSA_WITH_AES_128_GCM_SHA256)) && defined(USE_IDENTITY_CERTIFICATES) + +# include +# include +# include +# include + +/* Key material. */ +# ifdef USE_ECC +# include "testkeys/EC/256_EC.h" +# include "testkeys/EC/256_EC_KEY.h" +# include "testkeys/EC/256_EC_CA.h" +# ifdef USE_SECP384R1 +# include "testkeys/EC/384_EC_SHA384.h" +# include "testkeys/EC/384_EC_KEY.h" +# include "testkeys/EC/384_EC_CA_SHA384.h" +# endif +# ifdef USE_SECP521R1 +# include "testkeys/EC/521_EC_SHA512.h" +# include "testkeys/EC/521_EC_KEY.h" +# include "testkeys/EC/521_EC_CA_SHA512.h" +# endif +# include "testkeys/EC/ALL_EC_CAS.h" +# endif +# ifdef USE_RSA +# include "testkeys/RSA/2048_RSA.h" +# include "testkeys/RSA/2048_RSA_KEY.h" +# include "testkeys/RSA/2048_RSA_CA.h" +# include "testkeys/RSA/3072_RSA_CA.h" +# endif + +# ifdef SERVER_IP_ADDRESS +# define TO_STRING_INNER(x) #x +# define TO_STRING(x) TO_STRING_INNER(x) +static const char *ip_address_str = TO_STRING(SERVER_IP_ADDRESS); +# else +static const char *ip_address_str = "127.0.0.1"; +# endif + +# ifndef SERVER_PORT +# define SERVER_PORT 4433 +# endif + +void cleanup(ssl_t *ssl, sslKeys_t *keys); +int load_keys(sslKeys_t *keys); + +/* Certificate callback. See section 6 in the API manual for details. + In this test, we do no extra checks of our own; we simply accept + the result of MatrixSSL's internal certificate validation. */ +static int32_t certCb(ssl_t *ssl, psX509Cert_t *cert, int32_t alert) +{ + return alert; +} + +static unsigned char g_httpRequestHdr[] = "GET ./index.html HTTP/1.0\r\n" + "Host: localhost\r\n" + "User-Agent: MatrixSSL 4.0.1\r\n" + "Accept: */*\r\n" + "Content-Length: 0\r\n" + "\r\n"; + +# ifdef USE_ROT_CRYPTO +# include "../../crypto-rot/rot/include/api_val.h" +static uint32_t g_longTermAssets[] = { VAL_ASSETID_INVALID, + VAL_ASSETID_INVALID }; +# define IX_ECC 0 +# define IX_RSA 1 + +/* If enabled, getLongTermPrivAsset shall be called to fetch a + private key asset ID. If not enabled, a plaintext test key + shall be used. */ +# define LOAD_PRIVKEY_ASSET + +# ifdef LOAD_PRIVKEY_ASSET +uint32_t getLongTermPrivAsset(int keyType); +extern ValStatus_t psRotAssetFree(ValAssetId_t *asset); +# endif /* LOAD_PRIVKEY_ASSET */ +# endif /* USE_ROT_CRYPTO */ + +/* Send application data over an established TLS connection. */ +static int32_t sendAppData(ssl_t *ssl, + unsigned char *data, + size_t dataLen) +{ + int32_t rc; + unsigned char *buf; + + /* Get pointer to the internal plaintext buffer and fill + it with the plaintext data. */ + rc = matrixSslGetWritebuf(ssl, &buf, dataLen); + if (rc < dataLen) + { + return PS_FAILURE; + } + memcpy(buf, data, dataLen); + + /* Encrypt. */ + rc = matrixSslEncodeWritebuf(ssl, dataLen); + if (rc < 0) + { + return PS_FAILURE; + } + /* Ask the main loop to send it over the wire. */ + return MATRIXSSL_REQUEST_SEND; +} + +int main(int argc, char **argv) +{ + uint16_t sigAlgs[] = { +# ifdef USE_ECC + sigalg_ecdsa_secp256r1_sha256, +# ifdef USE_SECP384R1 + sigalg_ecdsa_secp384r1_sha384, +# endif +# ifdef USE_SECP521R1 + sigalg_ecdsa_secp521r1_sha512, +# endif +# endif +# ifdef USE_RSA +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha256, +# ifdef USE_SHA384 + sigalg_rsa_pss_rsae_sha384, +# endif +# endif + sigalg_rsa_pkcs1_sha256 +# endif + }; + int32_t sigAlgsLen = sizeof(sigAlgs)/sizeof(sigAlgs[0]); + psCipher16_t ciphersuites[] = { +# ifdef USE_TLS_1_3 + TLS_AES_128_GCM_SHA256, +# endif +# ifdef USE_ECC + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, +# endif +# ifdef USE_RSA +# ifdef USE_ECC + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, +# endif + TLS_RSA_WITH_AES_128_GCM_SHA256 +# endif + }; + int32_t ciphersuitesLen = sizeof(ciphersuites)/sizeof(ciphersuites[0]); + psProtocolVersion_t versions[] = + { +# ifdef USE_TLS_1_3 + v_tls_1_3, +# endif + v_tls_1_2 + }; + int32_t versionsLen = sizeof(versions)/sizeof(versions[0]); + sslSessOpts_t opts; + sslKeys_t *keys = NULL; + int32_t rc; + uint32_t len; + ssl_t *ssl = NULL; + unsigned char *buf; + ssize_t nrecv, nsent; + int fd; + struct sockaddr_in addr; + + rc = matrixSslOpen(); + if (rc < 0) + { + return EXIT_FAILURE; + } + + /* Allocate a new key structure. */ + rc = matrixSslNewKeys(&keys, NULL); + if (rc < 0) + { + cleanup(ssl, keys); + return EXIT_FAILURE; + } + + /* Load key material into 'keys'. The called function is a simple + wrapper for matrixSslLoadKeysMem. */ + rc = load_keys(keys); + if (rc < 0) + { + cleanup(ssl, keys); + return EXIT_FAILURE; + } + + /* Setup session options. */ + Memset(&opts, 0, sizeof(opts)); /* Important. */ + + /* Set supported protocol versions. */ + rc = matrixSslSessOptsSetClientTlsVersions( + &opts, + versions, + versionsLen); + if (rc < 0) + { + printf("matrixSslSessOptsSetClientTlsVersions failed: %d\n", rc); + cleanup(ssl, keys); + return EXIT_FAILURE; + } + +# ifdef USE_ECC + /* Set supported ECC curves for signatures and key exchange + The RoT Edition only supports the P-256, P-384 and P-521 + curves. */ + opts.ecFlags = IS_SECP256R1; +# ifdef USE_SECP384R1 + opts.ecFlags |= IS_SECP384R1; +# endif +# ifdef USE_SECP521R1 + opts.ecFlags |= IS_SECP521R1; +# endif +# endif + + /* Set supported signature algorithms. */ + rc = matrixSslSessOptsSetSigAlgs( + &opts, + sigAlgs, + sigAlgsLen); + if (rc < 0) + { + printf("matrixSslSessOptsSetSigAlgs failed: %d\n", rc); + cleanup(ssl, keys); + return EXIT_FAILURE; + } + + /* Create a new session and the ClientHello message. */ + rc = matrixSslNewClientSession( + &ssl, + keys, + NULL, + ciphersuites, + ciphersuitesLen, + certCb, + NULL, + NULL, + NULL, + &opts); + if (rc < 0) + { + printf("matrixSslNewClientSession failed: %d\n", rc); + cleanup(ssl, keys); + return EXIT_FAILURE; + } + + /* Open the TCP connection. */ + Memset((char *) &addr, 0x0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons((short) SERVER_PORT); + addr.sin_addr.s_addr = inet_addr(ip_address_str); + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + { + printf("socket failed: %d\n", fd); + cleanup(ssl, keys); + return EXIT_FAILURE; + } + printf("Connecting to %s: %d\n", ip_address_str, SERVER_PORT); + rc = connect(fd, (struct sockaddr *) &addr, sizeof(addr)); + if (rc < 0) + { + close(fd); + printf("connect failed: %d\n", rc); + cleanup(ssl, keys); + return EXIT_FAILURE; + } + +WRITE_MORE: + /* Get pointer to the output data to send. */ + rc = matrixSslGetOutdata(ssl, &buf); + while (rc > 0) + { + len = rc; + + /* Send it over the wire. */ + nsent = send(fd, buf, len, 0); + if (nsent <= 0) + { + printf("send() failed\n"); + goto out_fail; + } + + /* Inform the TLS library how much we managed to send. + Return code will tell us of what to do next. */ + rc = matrixSslSentData(ssl, nsent); + if (rc < 0) + { + printf("matrixSslSentData failed: %d\n", rc); + goto out_fail; + } + else if (rc == MATRIXSSL_REQUEST_CLOSE) + { + printf("Closing connection\n"); + goto out_ok; + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + printf("Handshake complete\n"); + /* Send app data over the encrypted connection. */ + rc = sendAppData( + ssl, + g_httpRequestHdr, + strlen((const char *)g_httpRequestHdr)); + if (rc < 0) + { + goto out_fail; + } + goto WRITE_MORE; + } + /* rc == PS_SUCCESS. */ + + /* More data to send? */ + rc = matrixSslGetOutdata(ssl, &buf); + } + +READ_MORE: + /* Get pointer to buffer where incoming data should be read into. */ + rc = matrixSslGetReadbuf(ssl, &buf); + if (rc < 0) + { + goto out_fail; + } + len = rc; + + /* Read data from the wire. */ + nrecv = recv(fd, buf, len, 0); + if (nrecv < 0) + { + goto out_fail; + } + + /* Ask the TLS library to process the data we read. + Return code will tell us what to do next. */ + rc = matrixSslReceivedData( + ssl, + nrecv, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + printf("Handshake complete\n"); + /* Send app data over the encrypted connection. */ + rc = sendAppData( + ssl, + g_httpRequestHdr, + strlen((const char *)g_httpRequestHdr)); + if (rc < 0) + { + goto out_fail; + } + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_SEND) + { + /* Handshake messages or an alert have been encoded. + These need to be sent over the wire. */ + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_RECV) + { + /* Handshake still in progress. Need more messages + from the peer. */ + goto READ_MORE; + } + else if (rc == MATRIXSSL_APP_DATA) + { + /* We received encrypted application data from the peer. */ +# ifdef SIMPLE_CLIENT_PRINT_DECRYPTED_APP_DATA + /* For test purposes, just print it out. */ + psTraceBytes("Decrypted app data", buf, len); +# endif + /* Inform the TLS library that we "processed" the data. */ + rc = matrixSslProcessedData( + ssl, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + /* This test ends after successful reception of encrypted + app data from the peer. */ + goto out_ok; + } + +out_ok: + rc = PS_SUCCESS; + +out_fail: + cleanup(ssl, keys); + close(fd); + + if (rc == PS_SUCCESS) + { + return EXIT_SUCCESS; + } + else + { + return EXIT_FAILURE; + } +} + +# ifdef LOAD_PRIVKEY_ASSET +extern ValStatus_t psRotAssetFree(ValAssetId_t *asset); +# endif + +void cleanup(ssl_t *ssl, sslKeys_t *keys) +{ + + if (ssl) + { + matrixSslDeleteSession(ssl); + } + if (keys) + { + matrixSslDeleteKeys(keys); + } + +# ifdef LOAD_PRIVKEY_ASSET + psRotAssetFree(&g_longTermAssets[IX_ECC]); + psRotAssetFree(&g_longTermAssets[IX_RSA]); +# endif + + matrixSslClose(); +} + +/* Load certificate and key material. + When using RoT, the private keys can also be provided in the form + of a long term asset IDs. */ +int load_keys(sslKeys_t *keys) +{ +# ifdef LOAD_PRIVKEY_ASSET + ValAssetId_t privAssetEcdsa = VAL_ASSETID_INVALID; + ValAssetId_t privAssetRsa = VAL_ASSETID_INVALID; +# else + uint32_t privAssetEcdsa = 0; + uint32_t privAssetRsa = 0; +# endif + int32_t rc; + matrixSslLoadKeysOpts_t keyOpts; + + (void)privAssetRsa; + +# ifdef LOAD_PRIVKEY_ASSET +# ifdef USE_ECC + privAssetEcdsa = getLongTermPrivAsset(PS_ECC); +# endif +# ifdef USE_RSA + privAssetRsa = getLongTermPrivAsset(PS_RSA); +# endif /* USE_RSA */ +# endif /* LOAD_PRIVKEY_ASSET */ + + memset(&keyOpts, 0, sizeof(keyOpts)); + +# ifdef USE_ECC + keyOpts.privAssetCurveId = IANA_SECP256R1; + keyOpts.key_type = PS_ECC; + keyOpts.privAsset = privAssetEcdsa; + rc = matrixSslLoadKeysMem( + keys, + EC256, + EC256_SIZE, + EC256KEY, + EC256KEY_SIZE, + ECCAS, + sizeof(ECCAS), + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } +# endif + +# ifdef USE_SECP384R1 + keyOpts.privAssetCurveId = IANA_SECP384R1; + keyOpts.key_type = PS_ECC; + keyOpts.privAsset = 0; + rc = matrixSslLoadKeysMem( + keys, + EC384, + EC384_SIZE, + EC384KEY, + EC384KEY_SIZE, + ECCAS, + sizeof(ECCAS), + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } +# endif + +# ifdef USE_SECP521R1 + keyOpts.privAssetCurveId = IANA_SECP521R1; + keyOpts.key_type = PS_ECC; + keyOpts.privAsset = 0; + rc = matrixSslLoadKeysMem( + keys, + EC521, + EC521_SIZE, + EC521KEY, + EC521KEY_SIZE, + ECCAS, + sizeof(ECCAS), + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } +# endif + + /* If RSA is enabled in the compile-time config, also load + RSA keys and CA certs. */ +# ifdef USE_RSA + keyOpts.privAssetModulusNBytes = 256; + keyOpts.key_type = PS_RSA; + keyOpts.privAsset = privAssetRsa; + rc = matrixSslLoadKeysMem( + keys, + RSA2048, + RSA2048_SIZE, + RSA2048KEY, + RSA2048KEY_SIZE, + RSA2048CA, + RSA2048CA_SIZE, + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } +# endif + + return PS_SUCCESS; +} + +# ifdef LOAD_PRIVKEY_ASSET +/* Return the RoT asset ID of the long-term private key asset. */ +uint32_t getLongTermPrivAsset(int keyType) +{ + int32_t rc; + psPubKey_t key; +# ifdef USE_ECC + const psEccCurve_t *curve; +# endif + ValAssetId_t asset; + + /* + Test implementation: simply load the key from plaintext. +*/ + switch (keyType) + { +# ifdef USE_ECC + case PS_ECC: + rc = getEccParamById(IANA_SECP256R1, &curve); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + key.key.ecc.rotKeyType = ps_ecc_key_type_ecdsa; + rc = psEccParsePrivKey( + NULL, + EC256KEY, + EC256KEY_SIZE, + &key.key.ecc, + curve); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + + asset = key.key.ecc.privAsset; + g_longTermAssets[IX_ECC] = asset; + + /* Clear everything else from the key, except the asset ID. */ + key.key.ecc.longTermPrivAsset = PS_TRUE; + psEccClearKey(&key.key.ecc); + + break; +# endif +# ifdef USE_RSA + case PS_RSA: + rc = psRsaParsePkcs1PrivKey( + NULL, + RSA2048KEY, + RSA2048KEY_SIZE, + &key.key.rsa); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + asset = key.key.rsa.privSigAsset; + g_longTermAssets[IX_RSA] = asset; + + /* Clear everything else from the key, except the asset ID. */ + key.key.rsa.longTermPrivAsset = PS_TRUE; + psRsaClearKey(&key.key.rsa); + + break; +# endif + default: + printf("Unsupported key type\n"); + return VAL_ASSETID_INVALID; + } + + return asset; +} +# endif /* # LOAD_PRIVKEY_ASSET */ + +# else +int main(int argc, char **argv) +{ +# ifndef USE_CLIENT_SIDE_SSL + printf("This test requires USE_CLIENT_SIDE_SSL\n"); +# endif +# ifndef USE_TLS_1_2 + printf("This test requires USE_TLS_1_2\n"); +# endif +# if !defined(USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) && !defined(USE_TLS_RSA_WITH_AES_128_GCM_SHA256) + printf("This test requires USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 " \ + "or USE_TLS_RSA_WITH_AES_128_GCM_SHA256\n"); +# endif +# ifndef USE_IDENTITY_CERTIFICATES + printf("This test requires USE_IDENTITY_CERTIFICATES\n"); +# endif + return 1; +} +# endif /* USE_CLIENT_SIDE_SSL && USE_TLS_1_2 && USE_SECP256R1 && USE_SHA256 && USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 && USE_IDENTITY_CERTIFICATES */ diff --git a/apps/ssl/simpleServer.c b/apps/ssl/simpleServer.c new file mode 100644 index 0000000..edb8c15 --- /dev/null +++ b/apps/ssl/simpleServer.c @@ -0,0 +1,617 @@ +/** + * @file simpleServer.c + * @version $Format:%h%d$ + * + * Simple MatrixSSL blocking server example. + * - TLS 1.2 only + * - P-256 and ECDSA only + * - Only 1 simultaneous connection. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "matrixssl/matrixsslApi.h" + +# if defined(USE_SERVER_SIDE_SSL) && defined(USE_TLS_1_2) && defined(USE_SECP256R1) && defined(USE_SHA256) && defined(USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) + +# include +# include +# include +# include + +/* Key material. */ +# include "testkeys/EC/256_EC.h" +# include "testkeys/EC/256_EC_KEY.h" +# include "testkeys/EC/256_EC_CA.h" +# ifdef USE_RSA +# include "testkeys/RSA/2048_RSA.h" +# include "testkeys/RSA/2048_RSA_KEY.h" +# include "testkeys/RSA/3072_RSA.h" +# include "testkeys/RSA/3072_RSA_KEY.h" +# include "testkeys/RSA/2048_RSA_CA.h" +# endif + +# ifndef SERVER_PORT +# define SERVER_PORT 4433 +# endif + +static const char g_httpResponseHdr[] = "HTTP/1.0 200 OK\r\n" + "Server: MatrixSSL 4.0.1\r\n" + "Pragma: no-cache\r\n" + "Cache-Control: no-cache\r\n" + "Content-type: text/plain\r\n" + "Content-length: 9\r\n" + "\r\n" + "MatrixSSL"; + +void cleanup(ssl_t *ssl, sslKeys_t *keys, int fd, int sock_fd); +int load_keys(sslKeys_t *keys); + +# ifdef USE_ROT_CRYPTO +# include "../../crypto-rot/rot/include/api_val.h" +static uint32_t g_longTermAssets[] = { VAL_ASSETID_INVALID, + VAL_ASSETID_INVALID }; +# define IX_ECC 0 +# define IX_RSA 1 + +/* If enabled, getLongTermPrivAsset shall be called to fetch a + private key asset ID. If not enabled, a plaintext test key + shall be used. */ +# define LOAD_PRIVKEY_ASSET + +# ifdef LOAD_PRIVKEY_ASSET +uint32_t getLongTermPrivAsset(int keyType); +extern ValStatus_t psRotAssetFree(ValAssetId_t *asset); +# endif /* LOAD_PRIVKEY_ASSET */ +# endif /* USE_ROT_CRYPTO */ + +/* Send application data over an established TLS connection. */ +static int32_t sendAppData(ssl_t *ssl, + const unsigned char *data, + size_t dataLen) +{ + int32_t rc; + unsigned char *buf; + + psTraceBytes("Sending app data", data, dataLen); + /* Get pointer to the internal plaintext buffer and fill + it with the plaintext data. */ + rc = matrixSslGetWritebuf(ssl, &buf, dataLen); + if (rc < dataLen) + { + return PS_FAILURE; + } + memcpy(buf, data, dataLen); + + /* Encrypt. */ + rc = matrixSslEncodeWritebuf(ssl, dataLen); + if (rc < 0) + { + return PS_FAILURE; + } + /* Ask the main loop to send it over the wire. */ + return MATRIXSSL_REQUEST_SEND; +} + +int main(int argc, char **argv) +{ + uint16_t sigAlgs[] = { + sigalg_ecdsa_secp256r1_sha256, +# ifdef USE_SECP384R1 + sigalg_ecdsa_secp384r1_sha384, +# endif +# ifdef USE_SECP521R1 + sigalg_ecdsa_secp521r1_sha512, +# endif +# ifdef USE_RSA +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha256, +# endif + sigalg_rsa_pkcs1_sha256 +# endif + }; + int32_t sigAlgsLen = sizeof(sigAlgs)/sizeof(sigAlgs[0]); + psProtocolVersion_t versions[] = + { +# ifdef USE_TLS_1_3 + v_tls_1_3, +# endif + v_tls_1_2 + }; + int32_t versionsLen = sizeof(versions)/sizeof(versions[0]); + sslSessOpts_t opts; + sslKeys_t *keys = NULL; + int32_t rc; + uint32_t len; + ssl_t *ssl = NULL; + unsigned char *buf; + ssize_t nrecv, nsent; + int fd, sock_fd; + struct sockaddr_in addr; + int done_reading; + + rc = matrixSslOpen(); + if (rc < 0) + { + return EXIT_FAILURE; + } + + rc = matrixSslNewKeys(&keys, NULL); + if (rc < 0) + { + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Load key material into 'keys'. The called function is a simple + wrapper for matrixSslLoadKeysMem. */ + rc = load_keys(keys); + if (rc < 0) + { + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Setup session options. */ + Memset(&opts, 0, sizeof(opts)); /* Important. */ + + /* Set protocol versions. */ + rc = matrixSslSessOptsSetServerTlsVersions( + &opts, + versions, + versionsLen); + if (rc < 0) + { + printf("matrixSslSessOptsSetServerTlsVersions failed: %d\n", rc); + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Set supported ECC curves for signatures and key exchange + Currently, the RoT Edition only supports the P-256 curve. */ + opts.ecFlags = IS_SECP256R1; + + /* Set supported signature algorithms. */ + rc = matrixSslSessOptsSetSigAlgs( + &opts, + sigAlgs, + sigAlgsLen); + if (rc < 0) + { + printf("matrixSslSessOptsSetSigAlgs failed: %d\n", rc); + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Start listening to a TCP port for connections. */ + Memset((char *) &addr, 0x0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons((short) SERVER_PORT); + addr.sin_addr.s_addr = INADDR_ANY; + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + { + printf("socket failed: %d\n", fd); + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (rc < 0) + { + printf("bind failed: %d\n", rc); + cleanup(ssl, keys, fd, 0); + return EXIT_FAILURE; + } + rc = listen(fd, 1); + if (rc < 0) + { + printf("listen failed: %d\n", rc); + cleanup(ssl, keys, fd, 0); + return EXIT_FAILURE; + } + sock_fd = accept(fd, NULL, NULL); + if (rc < 0) + { + printf("accept failed: %d\n", rc); + cleanup(ssl, keys, fd, sock_fd); + return EXIT_FAILURE; + } + printf("Received new connection\n"); + + /* Create the server TLS session. */ + rc = matrixSslNewServerSession( + &ssl, + keys, + NULL, /* No certCb -> no client auth required. */ + &opts); + if (rc < 0) + { + printf("matrixSslNewServerSession failed: %d\n", rc); + cleanup(ssl, keys, fd, sock_fd); + return EXIT_FAILURE; + } + + done_reading = 0; + + while(!done_reading) + { +READ_MORE: + /* Get pointer to buffer where incoming data should be read into. */ + rc = matrixSslGetReadbuf(ssl, &buf); + if (rc < 0) + { + goto out_fail; + } + len = rc; + + /* Read data from the wire. */ + nrecv = recv(sock_fd, buf, len, 0); + if (nrecv < 0) + { + goto out_fail; + } + + /* Ask the TLS library to process the data we read. + Return code will tell us what to do next. */ + rc = matrixSslReceivedData( + ssl, + nrecv, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + else if (rc == MATRIXSSL_RECEIVED_ALERT) + { + /* Handle successful connection closure and and alerts caused + by errors. */ + if (buf[1] == SSL_ALERT_CLOSE_NOTIFY) + { + printf("Exiting: received close_notify from peer\n"); + goto out_ok; + } + else + { + printf("Exiting: received alert\n"); + goto out_fail; + } + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + printf("Handshake complete\n"); + /* Send app data over the encrypted connection. */ + rc = sendAppData( + ssl, + (const unsigned char *)g_httpResponseHdr, + strlen(g_httpResponseHdr)); + if (rc < 0) + { + goto out_fail; + } + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_SEND) + { + /* Handshake messages or an alert have been encoded. + These need to be sent over the wire. */ + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_RECV) + { + /* Handshake still in progress. Need more messages + from the peer. */ + goto READ_MORE; + } + else if (rc == MATRIXSSL_APP_DATA) + { + /* We received encrypted application data from the peer. + Just print it out here. */ + psTraceBytes("Decrypted app data", buf, len); + /* Inform the TLS library that we "processed" the data. */ + rc = matrixSslProcessedData( + ssl, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + /* Send our HTTP response over the encrypted connection. */ + rc = sendAppData( + ssl, + (const unsigned char *)g_httpResponseHdr, + strlen(g_httpResponseHdr)); + if (rc < 0) + { + goto out_fail; + } + /* This test ends after we have sent our response. */ + done_reading = 1; + } + + WRITE_MORE: + /* Get pointer to the output data to send. */ + rc = matrixSslGetOutdata(ssl, &buf); + while (rc > 0) + { + len = rc; + + /* Send it over the wire. */ + nsent = send(sock_fd, buf, len, 0); + if (nsent <= 0) + { + printf("send() failed\n"); + goto out_fail; + } + + /* Inform the TLS library how much we managed to send. + Return code will tell us of what to do next. */ + rc = matrixSslSentData(ssl, nsent); + if (rc < 0) + { + printf("matrixSslSentData failed: %d\n", rc); + goto out_fail; + } + else if (rc == MATRIXSSL_REQUEST_CLOSE) + { + printf("Closing connection\n"); + goto out_ok; + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + printf("Handshake complete\n"); + /* Try to receive encrypted app data from the client. */ + goto READ_MORE; + } + /* rc == PS_SUCCESS. */ + + /* More data to send? */ + rc = matrixSslGetOutdata(ssl, &buf); + } + } + +out_ok: + rc = PS_SUCCESS; + +out_fail: + cleanup(ssl, keys, fd, sock_fd); + + if (rc == PS_SUCCESS) + { + return 0; + } + else + { + return EXIT_FAILURE; + } +} + +# ifdef LOAD_PRIVKEY_ASSET +extern ValStatus_t psRotAssetFree(ValAssetId_t *asset); +# endif + +void cleanup(ssl_t *ssl, sslKeys_t *keys, int fd, int sock_fd) +{ + + if (ssl) + { + matrixSslDeleteSession(ssl); + } + if (keys) + { + matrixSslDeleteKeys(keys); + } + if (fd != 0) + { + close(fd); + } + if (sock_fd != 0) + { + close(sock_fd); + } + +# ifdef LOAD_PRIVKEY_ASSET + psRotAssetFree(&g_longTermAssets[IX_ECC]); + psRotAssetFree(&g_longTermAssets[IX_RSA]); +# endif + + matrixSslClose(); +} + +/* Load certificate and key material. + When using RoT, the private keys can also be provided in the form + of a long term asset IDs. */ +int load_keys(sslKeys_t *keys) +{ +# ifdef LOAD_PRIVKEY_ASSET + ValAssetId_t privAssetEcdsa = VAL_ASSETID_INVALID; + ValAssetId_t privAssetRsa = VAL_ASSETID_INVALID; +# else + uint32_t privAssetEcdsa = 0; + uint32_t privAssetRsa = 0; +# endif + int32_t rc; + matrixSslLoadKeysOpts_t keyOpts; + + (void)privAssetRsa; + +# ifdef LOAD_PRIVKEY_ASSET + privAssetEcdsa = getLongTermPrivAsset(PS_ECC); +# ifdef USE_RSA + privAssetRsa = getLongTermPrivAsset(PS_RSA); +# endif /* USE_RSA */ +# endif /* LOAD_PRIVKEY_ASSET */ + + memset(&keyOpts, 0, sizeof(keyOpts)); + +# ifndef USE_PKCS1_PSS + keyOpts.privAssetCurveId = IANA_SECP256R1; + keyOpts.key_type = PS_ECC; + keyOpts.privAsset = privAssetEcdsa; + rc = matrixSslLoadKeysMem( + keys, + EC256, + EC256_SIZE, + EC256KEY, + EC256KEY_SIZE, + EC256CA, + EC256CA_SIZE, + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } + + /* If RSA is enabled in the compile-time config, also load + RSA keys and CA certs. */ +# ifdef USE_RSA + /* For slightly better test coverage, we use the 3072-bit RSA + test key here, while simpleClient uses a 2048-bit one. */ + keyOpts.privAssetModulusNBytes = 384; + keyOpts.key_type = PS_RSA; + keyOpts.privAsset = privAssetRsa; + rc = matrixSslLoadKeysMem( + keys, + RSA3072, + RSA3072_SIZE, + RSA3072KEY, + RSA3072KEY_SIZE, + RSA2048CA, + RSA2048CA_SIZE, + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } +# endif +# endif /* USE_PKCS1_PSS */ + +# ifdef USE_PKCS1_PSS + /* This one is always loaded from mem; not a "long-term" asset. */ + keyOpts.privAssetModulusNBytes = 256; + keyOpts.key_type = PS_RSA; + keyOpts.privAsset = 0; + rc = matrixSslLoadKeysMem( + keys, + RSA2048, + RSA2048_SIZE, + RSA2048KEY, + RSA2048KEY_SIZE, + RSA2048CA, + RSA2048CA_SIZE, + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } +# endif + + return PS_SUCCESS; +} + +# ifdef LOAD_PRIVKEY_ASSET +/* Return the RoT asset ID of the long-term private key asset. */ +uint32_t getLongTermPrivAsset(int keyType) +{ + int32_t rc; + psPubKey_t key; + const psEccCurve_t *curve; + ValAssetId_t asset; + + /* + Test implementation: simply load the key from plaintext. +*/ + switch (keyType) + { + case PS_ECC: + rc = getEccParamById(IANA_SECP256R1, &curve); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + key.key.ecc.rotKeyType = ps_ecc_key_type_ecdsa; + rc = psEccParsePrivKey( + NULL, + EC256KEY, + EC256KEY_SIZE, + &key.key.ecc, + curve); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + + asset = key.key.ecc.privAsset; + g_longTermAssets[IX_ECC] = asset; + + /* Clear everything else from the key, except the asset ID. */ + key.key.ecc.longTermPrivAsset = PS_TRUE; + psEccClearKey(&key.key.ecc); + + break; +# ifdef USE_RSA + case PS_RSA: + rc = psRsaParsePkcs1PrivKey( + NULL, + RSA3072KEY, + RSA3072KEY_SIZE, + &key.key.rsa); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + asset = key.key.rsa.privSigAsset; + g_longTermAssets[IX_RSA] = asset; + + /* Clear everything else from the key, except the asset ID. */ + key.key.rsa.longTermPrivAsset = PS_TRUE; + psRsaClearKey(&key.key.rsa); + + break; +# endif + default: + printf("Unsupported key type\n"); + return VAL_ASSETID_INVALID; + } + + return asset; +} +# endif /* # LOAD_PRIVKEY_ASSET */ + +# else +int main(int argc, char **argv) +{ + printf("This test requires USE_SERVER_SIDE_SSL, USE_TLS_1_2, "\ + "USE_SECP256R1, USE_SHA256 and " \ + "USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.\n"); + return 1; +} +# endif /* USE_SERVER_SIDE_SSL && USE_TLS_1_2 && USE_SECP256R1 && USE_SHA256 && USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 */ diff --git a/apps/ssl/simpleServerRecvFile.c b/apps/ssl/simpleServerRecvFile.c new file mode 100644 index 0000000..ef96f77 --- /dev/null +++ b/apps/ssl/simpleServerRecvFile.c @@ -0,0 +1,646 @@ +/** + * @file simpleServer.c + * @version $Format:%h%d$ + * + * Simple MatrixSSL blocking server example. + * - TLS 1.2 only + * - P-256 and ECDSA only + * - Only 1 simultaneous connection. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "matrixssl/matrixsslApi.h" + +# if defined(USE_SERVER_SIDE_SSL) && defined(USE_TLS_1_2) && defined(USE_SECP256R1) && defined(USE_SHA256) && defined(USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) + +# include +# include +# include +# include + +/* Key material. */ +# include "testkeys/EC/256_EC.h" +# include "testkeys/EC/256_EC_KEY.h" +# include "testkeys/EC/256_EC_CA.h" +# ifdef USE_RSA +# include "testkeys/RSA/3072_RSA.h" +# include "testkeys/RSA/3072_RSA_KEY.h" +# include "testkeys/RSA/2048_RSA_CA.h" +# endif + +# ifndef SERVER_PORT +# define SERVER_PORT 4433 +# endif + +static const char g_httpResponseHdr[] = "HTTP/1.0 200 OK\r\n" + "Server: MatrixSSL 4.0.1\r\n" + "Pragma: no-cache\r\n" + "Cache-Control: no-cache\r\n" + "Content-type: text/plain\r\n" + "Content-length: 9\r\n" + "\r\n" + "MatrixSSL"; + +void cleanup(ssl_t *ssl, sslKeys_t *keys, int fd, int sock_fd); +int load_keys(sslKeys_t *keys); + +# ifdef USE_ROT_CRYPTO +# include "../../crypto-rot/rot/include/api_val.h" +static uint32_t g_longTermAssets[] = { VAL_ASSETID_INVALID, + VAL_ASSETID_INVALID }; +# define IX_ECC 0 +# define IX_RSA 1 + +/* If enabled, getLongTermPrivAsset shall be called to fetch a + private key asset ID. If not enabled, a plaintext test key + shall be used. */ +# define LOAD_PRIVKEY_ASSET + +# ifdef LOAD_PRIVKEY_ASSET +uint32_t getLongTermPrivAsset(int keyType); +extern ValStatus_t psRotAssetFree(ValAssetId_t *asset); +# endif /* LOAD_PRIVKEY_ASSET */ +# endif /* USE_ROT_CRYPTO */ + +/* Send application data over an established TLS connection. */ +static int32_t sendAppData(ssl_t *ssl, + const unsigned char *data, + size_t dataLen) +{ + int32_t rc; + unsigned char *buf; + + psTraceBytes("Sending app data", data, dataLen); + /* Get pointer to the internal plaintext buffer and fill + it with the plaintext data. */ + rc = matrixSslGetWritebuf(ssl, &buf, dataLen); + if (rc < dataLen) + { + return PS_FAILURE; + } + memcpy(buf, data, dataLen); + + /* Encrypt. */ + rc = matrixSslEncodeWritebuf(ssl, dataLen); + if (rc < 0) + { + return PS_FAILURE; + } + /* Ask the main loop to send it over the wire. */ + return MATRIXSSL_REQUEST_SEND; +} + +int main(int argc, char **argv) +{ + uint16_t sigAlgs[] = { + sigalg_ecdsa_secp256r1_sha256, +# ifdef USE_RSA + sigalg_rsa_pkcs1_sha256 +# endif + }; + int32_t sigAlgsLen = sizeof(sigAlgs)/sizeof(sigAlgs[0]); + psProtocolVersion_t versions[1]; + sslSessOpts_t opts; + sslKeys_t *keys = NULL; + int32_t rc; + uint32_t len; + ssl_t *ssl = NULL; + unsigned char *buf; + ssize_t nrecv, nsent; + int fd, sock_fd; + struct sockaddr_in addr; + int done_reading; + size_t file_size_nbytes = 0; + size_t file_received_nbytes = 0; + + rc = matrixSslOpen(); + if (rc < 0) + { + return EXIT_FAILURE; + } + + rc = matrixSslNewKeys(&keys, NULL); + if (rc < 0) + { + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Load key material into 'keys'. The called function is a simple + wrapper for matrixSslLoadKeysMem. */ + rc = load_keys(keys); + if (rc < 0) + { + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Setup session options. */ + Memset(&opts, 0, sizeof(opts)); /* Important. */ + + /* Set TLS 1.2 as the protocol version. */ + versions[0] = v_tls_1_2; + rc = matrixSslSessOptsSetServerTlsVersions( + &opts, + versions, + 1); + if (rc < 0) + { + printf("matrixSslSessOptsSetClientTlsVersions failed: %d\n", rc); + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Set supported ECC curves for signatures and key exchange + Currently, the RoT Edition only supports the P-256 curve. */ + opts.ecFlags = IS_SECP256R1; + + /* Set supported signature algorithms. */ + rc = matrixSslSessOptsSetSigAlgs( + &opts, + sigAlgs, + sigAlgsLen); + if (rc < 0) + { + printf("matrixSslSessOptsSetSigAlgs failed: %d\n", rc); + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + + /* Start listening to a TCP port for connections. */ + Memset((char *) &addr, 0x0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons((short) SERVER_PORT); + addr.sin_addr.s_addr = INADDR_ANY; + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + { + printf("socket failed: %d\n", fd); + cleanup(ssl, keys, 0, 0); + return EXIT_FAILURE; + } + rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (rc < 0) + { + printf("bind failed: %d\n", rc); + cleanup(ssl, keys, fd, 0); + return EXIT_FAILURE; + } + rc = listen(fd, 1); + if (rc < 0) + { + printf("listen failed: %d\n", rc); + cleanup(ssl, keys, fd, 0); + return EXIT_FAILURE; + } + sock_fd = accept(fd, NULL, NULL); + if (rc < 0) + { + printf("accept failed: %d\n", rc); + cleanup(ssl, keys, fd, sock_fd); + return EXIT_FAILURE; + } + printf("Received new connection\n"); + + /* Create the server TLS session. */ + rc = matrixSslNewServerSession( + &ssl, + keys, + NULL, /* No certCb -> no client auth required. */ + &opts); + if (rc < 0) + { + printf("matrixSslNewServerSession failed: %d\n", rc); + cleanup(ssl, keys, fd, sock_fd); + return EXIT_FAILURE; + } + + done_reading = 0; + + while(!done_reading) + { +READ_MORE: + /* Get pointer to buffer where incoming data should be read into. */ + rc = matrixSslGetReadbuf(ssl, &buf); + if (rc < 0) + { + goto out_fail; + } + len = rc; + + printf("Got Readbuf of len: %zu\n", len); + + /* Read data from the wire. */ + nrecv = recv(sock_fd, buf, len, 0); + if (nrecv < 0) + { + goto out_fail; + } + printf("recv'd %zu bytes\n", nrecv); + +decrypt_more: + /* Ask the TLS library to process the data we read. + Return code will tell us what to do next. */ + rc = matrixSslReceivedData( + ssl, + nrecv, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + else if (rc == MATRIXSSL_RECEIVED_ALERT) + { + /* Handle successful connection closure and and alerts caused + by errors. */ + if (buf[1] == SSL_ALERT_CLOSE_NOTIFY) + { + printf("Exiting: received close_notify from peer\n"); + goto out_ok; + } + else + { + printf("Exiting: received alert\n"); + goto out_fail; + } + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + printf("Handshake complete\n"); + /* Send app data over the encrypted connection. */ + rc = sendAppData( + ssl, + (const unsigned char *)g_httpResponseHdr, + strlen(g_httpResponseHdr)); + if (rc < 0) + { + goto out_fail; + } + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_SEND) + { + /* Handshake messages or an alert have been encoded. + These need to be sent over the wire. */ + goto WRITE_MORE; + } + else if (rc == MATRIXSSL_REQUEST_RECV) + { + /* Handshake still in progress. Need more messages + from the peer. */ + goto READ_MORE; + } + else if (rc == MATRIXSSL_APP_DATA) + { + /* We received encrypted application data from the peer. + Just print it out here. */ + unsigned char *buf_begin = buf; + + //psTraceBytes("Decrypted app data", buf, len); + if (file_size_nbytes > 0) + { + file_received_nbytes += len; + } + else if ( len > 4) + { + if (!Strncmp(buf, "[file size=", strlen("[file size="))) + { + /* Read off the file size. */ + int i = strlen("[file size="); + int j = 0; + char len_str[16] = {0}; + int file_size; + + while (isdigit(buf[i])) + { + len_str[j++] = buf[i]; + i++; + } + if (buf[i] != ']') + { + printf("Wrong file header\n"); + goto out_fail; + } + i++; + + file_size = atoi(len_str); + file_size_nbytes = file_size; + printf("Receiving a file of size: %zu\n", file_size_nbytes); + file_received_nbytes = len - i + 1; + } + } + do + { + FILE *fp; + size_t nbytes; + + fp = fopen("app-data.txt", "ab"); + if (!fp) + { + printf("Could not open file: app-data.txt\n"); + } + nbytes = fwrite(buf, 1, len, fp); + if (nbytes != len) + { + printf("fwrite failed\n"); + } + fclose(fp); + + /* Inform the TLS library that we "processed" the data. */ + rc = matrixSslProcessedData( + ssl, + &buf, + &len); + if (rc < 0) + { + goto out_fail; + } + printf("matrixSslProcessedData rc: %d\n", rc); + } while (rc == MATRIXSSL_APP_DATA + || rc == MATRIXSSL_RECEIVED_ALERT); + + if (rc == MATRIXSSL_REQUEST_RECV || + file_received_nbytes < file_size_nbytes) + { + printf("Received %zu of %zu file bytes\n", + file_received_nbytes, file_size_nbytes); + goto READ_MORE; + } + + /* Send our HTTP response over the encrypted connection. */ + rc = sendAppData( + ssl, + (const unsigned char *)g_httpResponseHdr, + strlen(g_httpResponseHdr)); + if (rc < 0) + { + goto out_fail; + } + /* This test ends after we have sent our response. */ + done_reading = 1; + } + + WRITE_MORE: + /* Get pointer to the output data to send. */ + rc = matrixSslGetOutdata(ssl, &buf); + while (rc > 0) + { + len = rc; + + /* Send it over the wire. */ + nsent = send(sock_fd, buf, len, 0); + if (nsent <= 0) + { + printf("send() failed\n"); + goto out_fail; + } + + /* Inform the TLS library how much we managed to send. + Return code will tell us of what to do next. */ + rc = matrixSslSentData(ssl, nsent); + if (rc < 0) + { + printf("matrixSslSentData failed: %d\n", rc); + goto out_fail; + } + else if (rc == MATRIXSSL_REQUEST_CLOSE) + { + printf("Closing connection\n"); + goto out_ok; + } + else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) + { + printf("Handshake complete\n"); + /* Try to receive encrypted app data from the client. */ + goto READ_MORE; + } + /* rc == PS_SUCCESS. */ + + /* More data to send? */ + rc = matrixSslGetOutdata(ssl, &buf); + } + } + +out_ok: + rc = PS_SUCCESS; + +out_fail: + cleanup(ssl, keys, fd, sock_fd); + + if (rc == PS_SUCCESS) + { + return 0; + } + else + { + return EXIT_FAILURE; + } +} + +# ifdef LOAD_PRIVKEY_ASSET +extern ValStatus_t psRotAssetFree(ValAssetId_t *asset); +# endif + +void cleanup(ssl_t *ssl, sslKeys_t *keys, int fd, int sock_fd) +{ + + if (ssl) + { + matrixSslDeleteSession(ssl); + } + if (keys) + { + matrixSslDeleteKeys(keys); + } + if (fd != 0) + { + close(fd); + } + if (sock_fd != 0) + { + close(sock_fd); + } + +# ifdef LOAD_PRIVKEY_ASSET + psRotAssetFree(&g_longTermAssets[IX_ECC]); + psRotAssetFree(&g_longTermAssets[IX_RSA]); +# endif + + matrixSslClose(); +} + +/* Load certificate and key material. + When using RoT, the private keys can also be provided in the form + of a long term asset IDs. */ +int load_keys(sslKeys_t *keys) +{ +# ifdef LOAD_PRIVKEY_ASSET + ValAssetId_t privAssetEcdsa = VAL_ASSETID_INVALID; + ValAssetId_t privAssetRsa = VAL_ASSETID_INVALID; +# else + uint32_t privAssetEcdsa = 0; + uint32_t privAssetRsa = 0; +# endif + int32_t rc; + matrixSslLoadKeysOpts_t keyOpts; + + (void)privAssetRsa; + +# ifdef LOAD_PRIVKEY_ASSET + privAssetEcdsa = getLongTermPrivAsset(PS_ECC); +# ifdef USE_RSA + privAssetRsa = getLongTermPrivAsset(PS_RSA); +# endif /* USE_RSA */ +# endif /* LOAD_PRIVKEY_ASSET */ + + memset(&keyOpts, 0, sizeof(keyOpts)); + + keyOpts.privAssetCurveId = IANA_SECP256R1; + keyOpts.key_type = PS_ECC; + keyOpts.privAsset = privAssetEcdsa; + rc = matrixSslLoadKeysMem( + keys, + EC256, + EC256_SIZE, + EC256KEY, + EC256KEY_SIZE, + EC256CA, + EC256CA_SIZE, + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } + + /* If RSA is enabled in the compile-time config, also load + RSA keys and CA certs. */ +# ifdef USE_RSA + /* For slightly better test coverage, we use the 3072-bit RSA + test key here, while simpleClient uses a 2048-bit one. */ + keyOpts.privAssetModulusNBytes = 384; + keyOpts.key_type = PS_RSA; + keyOpts.privAsset = privAssetRsa; + rc = matrixSslLoadKeysMem( + keys, + RSA3072, + RSA3072_SIZE, + RSA3072KEY, + RSA3072KEY_SIZE, + RSA2048CA, + RSA2048CA_SIZE, + &keyOpts); + if (rc < 0) + { + printf("matrixSslLoadKeysMemRot failed: %d\n", rc); + return PS_FAILURE; + } +# endif + + return PS_SUCCESS; +} + +# ifdef LOAD_PRIVKEY_ASSET +/* Return the RoT asset ID of the long-term private key asset. */ +uint32_t getLongTermPrivAsset(int keyType) +{ + int32_t rc; + psPubKey_t key; + const psEccCurve_t *curve; + ValAssetId_t asset; + + /* + Test implementation: simply load the key from plaintext. +*/ + switch (keyType) + { + case PS_ECC: + rc = getEccParamById(IANA_SECP256R1, &curve); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + key.key.ecc.rotKeyType = ps_ecc_key_type_ecdsa; + rc = psEccParsePrivKey( + NULL, + EC256KEY, + EC256KEY_SIZE, + &key.key.ecc, + curve); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + + asset = key.key.ecc.privAsset; + g_longTermAssets[IX_ECC] = asset; + + /* Clear everything else from the key, except the asset ID. */ + key.key.ecc.longTermPrivAsset = PS_TRUE; + psEccClearKey(&key.key.ecc); + + break; +# ifdef USE_RSA + case PS_RSA: + rc = psRsaParsePkcs1PrivKey( + NULL, + RSA3072KEY, + RSA3072KEY_SIZE, + &key.key.rsa); + if (rc != PS_SUCCESS) + { + return VAL_ASSETID_INVALID; + } + asset = key.key.rsa.privSigAsset; + g_longTermAssets[IX_RSA] = asset; + + /* Clear everything else from the key, except the asset ID. */ + key.key.rsa.longTermPrivAsset = PS_TRUE; + psRsaClearKey(&key.key.rsa); + + break; +# endif + default: + printf("Unsupported key type\n"); + return VAL_ASSETID_INVALID; + } + + return asset; +} +# endif /* # LOAD_PRIVKEY_ASSET */ + +# else +int main(int argc, char **argv) +{ + printf("This test requires USE_SERVER_SIDE_SSL, USE_TLS_1_2, "\ + "USE_SECP256R1, USE_SHA256 and " \ + "USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.\n"); + return 1; +} +# endif /* USE_SERVER_SIDE_SSL && USE_TLS_1_2 && USE_SECP256R1 && USE_SHA256 && USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 */ diff --git a/configs/default/coreConfig.h b/configs/default/coreConfig.h index a0e9380..0255323 100644 --- a/configs/default/coreConfig.h +++ b/configs/default/coreConfig.h @@ -40,61 +40,10 @@ /* Debug and tracing configuration */ /******************************************************************************/ -/** - Select tracing facility. - Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and - allows log redirection. - - On the smallest embedded targets platform using PS_NO_LOGF may provide - footprint benefits but will limit logging capabilities. - */ - -/* Uncomment to use previous generation logging facility: */ -/* #define PS_NO_LOGF */ - -/* When using psLogf, logging messages by default go to the binary, but - they are not shown unless enabled by environment variables or - filter loaded with psLogfSetHookEnabledCheck() function. - - Enable macros below to completely remove specified logging class. */ -/* #define PS_NO_LOGF_FATAL */ -/* #define PS_NO_LOGF_ERROR */ -/* #define PS_NO_LOGF_WARNING */ -/* #define PS_NO_LOGF_INFO */ -/* #define PS_NO_LOGF_VERBOSE */ -/* #define PS_NO_LOGF_DEBUG */ -/* #define PS_NO_LOGF_TRACE */ -/* #define PS_NO_LOGF_CALL_TRACE */ - -/* MatrixSSL contains extensive tracing capabilities. The lines below - disable trace and call trace message levels, unless debug build. - Omitting the messages will improve performance and create smaller - executables with a degradation in debugging capabilities. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_TRACE -# define PS_NO_LOGF_TRACE -# endif -# ifndef PS_NO_LOGF_CALL_TRACE -# define PS_NO_LOGF_CALL_TRACE -# endif -# endif - -/* File and line information consumes some storage and may reveal details on - structure of software. This information is omitted from production builds, - but included within "debug build". If you want to include file and line - information also on production builds, disable the lines below. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_FILELINE -# define PS_NO_LOGF_FILELINE -# endif -# endif - /** Enable various levels of trace. When these option is turned off, messages are silently discarded and their text does not take space in the binary image. - Note: These are legacy configuration, and it is recommended to use - PS_NO_LOGF_* above, unless PS_NO_LOGF is set. */ /* #define USE_CORE_TRACE */ # ifndef NO_CORE_ERROR @@ -104,6 +53,16 @@ # define USE_CORE_ASSERT # endif +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + /******************************************************************************/ /* Other Configurable features */ /******************************************************************************/ @@ -116,6 +75,11 @@ /* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ # endif +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +/* #define NO_FILE_SYSTEM */ + /** Include the psCoreOsdepMutex family of APIs diff --git a/configs/default/cryptoConfig.h b/configs/default/cryptoConfig.h index 0e0944c..d3ac379 100644 --- a/configs/default/cryptoConfig.h +++ b/configs/default/cryptoConfig.h @@ -228,10 +228,14 @@ # define USE_X509/**< Enable minimal X.509 support. */ # define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ # define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ /**< Support extra distinguished name attributes not mentioned in RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ /* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ /* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ @@ -273,13 +277,12 @@ /* #define USE_OCSP *//**< @pre USE_SHA1 */ # ifdef USE_OCSP # define USE_OCSP_RESPONSE -# define USE_OCSP_REQUEST # elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) /** Enable parsing and writing of OCSP responses. This is enough to support OCSP stapling. */ -# define USE_OCSP_RESPONSE /**< @pre USE_SHA1 */ +# define USE_OCSP_RESPONSE/**< @pre USE_SHA1 */ #endif /* USE_OCSP */ /******************************************************************************/ @@ -295,6 +298,12 @@ # define USE_PKCS1_OAEP/* OAEP padding algorithm */ # define USE_PKCS1_PSS/* PSS padding algorithm */ +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +# define USE_BASE64_DECODE/* Allow decoding Base64-encoded data. */ +# define USE_PEM_DECODE/* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + #endif /* _h_PS_CRYPTOCONFIG */ /******************************************************************************/ diff --git a/configs/default/matrixsslConfig.h b/configs/default/matrixsslConfig.h index 6c7cea3..f39c60c 100644 --- a/configs/default/matrixsslConfig.h +++ b/configs/default/matrixsslConfig.h @@ -55,12 +55,14 @@ extern "C" { /******************************************************************************/ /** - Show which SSL messages are created and parsed + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. */ /* #define USE_SSL_HANDSHAKE_MSG_TRACE */ /** - Informational trace that could help pinpoint problems with SSL connections + Informational trace that could help pinpoint problems with TLS/DTLS + connections. */ /* #define USE_SSL_INFORMATIONAL_TRACE */ /* #define USE_DTLS_DEBUG_TRACE */ @@ -250,6 +252,14 @@ extern "C" { /* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ # endif +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + /******************************************************************************/ /** Client certificate authentication @@ -424,6 +434,11 @@ extern "C" { /* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ # endif +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + # ifdef __cplusplus } # endif diff --git a/configs/fulltest/coreConfig.h b/configs/fulltest/coreConfig.h new file mode 100644 index 0000000..0255323 --- /dev/null +++ b/configs/fulltest/coreConfig.h @@ -0,0 +1,109 @@ +/** + * @file coreConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for Matrix core module. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CORECONFIG +# define _h_PS_CORECONFIG + + +/******************************************************************************/ +/* Debug and tracing configuration */ +/******************************************************************************/ + +/** + Enable various levels of trace. + When these option is turned off, messages are silently + discarded and their text does not take space in the binary image. + */ +/* #define USE_CORE_TRACE */ +# ifndef NO_CORE_ERROR +# define USE_CORE_ERROR +# endif +# ifndef NO_CORE_ASSERT +# define USE_CORE_ASSERT +# endif + +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + +/******************************************************************************/ +/* Other Configurable features */ +/******************************************************************************/ + +/** + If enabled, calls to the psError set of APIs will perform a platform + abort on the exeutable to aid in debugging. + */ +# ifdef DEBUG +/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ +# endif + +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +/* #define NO_FILE_SYSTEM */ + +/** + Include the psCoreOsdepMutex family of APIs + + @note If intending to compile crypto-cl, then this flag should + always be set. +*/ +# ifndef NO_MULTITHREADING +# define USE_MULTITHREADING +# endif /* NO_MULTITHREADING */ + +/** + Include the psNetwork family of APIs. + + These APIs allow simple high-level socket api. + The API derive from BSD Sockets, and therefore it can only be used + on devices which have the prerequisitive APIs. + MatrixSSL itself can be used also be used without PS networking, but + many of example programs and MatrixSSLNet are based on PS networking. + */ +# ifndef NO_PS_NETWORKING +# define USE_PS_NETWORKING +# endif /* NO_PS_NETWORKING */ + +#endif /* _h_PS_CORECONFIG */ + +/******************************************************************************/ + diff --git a/configs/fulltest/cryptoConfig.h b/configs/fulltest/cryptoConfig.h new file mode 100644 index 0000000..23d38be --- /dev/null +++ b/configs/fulltest/cryptoConfig.h @@ -0,0 +1,309 @@ +/** + * @file cryptoConfig.h + * @version $Format:%h%d$ + * + * Configuration file for crypto features. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CRYPTOCONFIG +# define _h_PS_CRYPTOCONFIG + +/******************************************************************************/ +/* Configurable features */ +/******************************************************************************/ +/** + Define to enable psTrace*Crypto APIs for debugging the crypto module. + */ +/* #define USE_CRYPTO_TRACE */ + +# ifdef DEBUG +/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */ +# endif + +/******************************************************************************/ +/* + Use built-in cryptographic library delivered with MatrixSSL + */ +# define USE_NATIVE_RSA /* Default built-in software support */ + +/******************************************************************************/ +/** + Security related settings. + + @security MIN_*_BITS is the minimum supported key sizes in bits, weaker + keys will be rejected. + */ +# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */ + +# define MIN_RSA_BITS 1024 + +/* The configuration can define set minimum for RSA public exponent. + + For CL crypto, the default is 65537 (according to FIPS 186-4 standard). + It can be overridden on line below: + */ +/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */ + +# define MIN_DH_BITS 1024 + +# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */ + +/******************************************************************************/ +/** + Public-Key Algorithm Support. + */ +# define USE_RSA +# define USE_ECC +# define USE_DH +/**< @note Enable verification of DSA signatures in certificate validation. + Works only when using the CL/SL library. @pre USE_CERT_PARSE. */ +/* #define USE_DSA_VERIFY */ +# ifdef USE_DH +/**< @note Enable this if you intent to support Diffie-Hellman groups larger + than 4096. Usually such large groups are not used. */ +/* #define USE_LARGE_DH_GROUPS */ +# endif /* USE_DH */ +/**< @note Enable ECDHE with Curve25519. */ +# define USE_X25519 +/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures. + @pre USE_ECC, USE_SHA512. */ +# define USE_ED25519 + +/******************************************************************************/ +/** + Build the PKCS and ASN1 extra CL sublibraries. + These are needed by the CL_PKCS API. + */ + +/******************************************************************************/ + +/** + Define to enable the individual NIST Prime curves. + @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +# ifdef USE_ECC +# define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */ +# define USE_SECP224R1 +# define USE_SECP256R1/**< @security NIST_SHALL */ +# define USE_SECP384R1/**< @security NIST_SHALL */ +# define USE_SECP521R1 +# endif + +/** + Define to enable the individual Brainpool curves. + @see https://tools.ietf.org/html/rfc5639 + @security WARNING: Public points on Brainpool curves are not validated + */ +# ifdef USE_ECC +/* #define USE_BRAIN224R1 */ +/* #define USE_BRAIN256R1 */ +/* #define USE_BRAIN384R1 */ +/* #define USE_BRAIN512R1 */ +# endif + +/******************************************************************************/ +/** + Symmetric and AEAD ciphers. + @security Deprecated ciphers must be enabled in cryptolib.h + */ +/* #define USE_AES *//* Enable/Disable AES */ +# define USE_AES_CBC +# define USE_AES_GCM + +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ +# define USE_CHACHA20_POLY1305_IETF + +/** @security 3DES is still relatively secure, however is deprecated for TLS */ +# define USE_3DES + +/******************************************************************************/ +/** + Legacy ciphers. + These ciphers have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher below need to disabled according to RFC 7465. +*/ +/* #define USE_ARC4 */ + +/******************************************************************************/ +/** + Digest algorithms. + + @note SHA256 and above are used with TLS 1.2, and also used for + certificate signatures on some certificates regardless of TLS version. + + @security MD5 is deprecated, but still required in combination with SHA-1 + for TLS handshakes before TLS 1.2, meaning that the strength is at least + that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable + MD5 only for this purpose. The only other usage of MD5 by TLS is for + certificate signatures and MD5 based cipher suites. Both of which are + disabled at compile time by default. + + @security SHA1 will be deprecated in the future, but is still required in + combination with MD5 for versions prior to TLS 1.2. In addition, SHA1 + certificates are still commonly used, so SHA1 support may be needed + to validate older certificates. It is possible to completely disable + SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting + only with newer certificates. + */ +/* #define USE_SHA224 *//**< @note Used only for cert signature */ +# define USE_SHA256/**< @note Required for TLS 1.2 and above */ +# define USE_HMAC_SHA256 +# define USE_SHA384/**< @pre USE_SHA512 */ +# define USE_HMAC_SHA384 +# define USE_SHA512 + +/** + @security SHA-1 based hashes are deprecated but enabled by default + @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below. + */ +# define USE_SHA1 +# define USE_HMAC_SHA1 + +/** + @security MD5 is considered insecure, but required by TLS < 1.2 + @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below. + */ +# define USE_MD5 +# define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */ +# define USE_HMAC_MD5 + +/** + @security MD2 is considered insecure, but is sometimes used for + verification of legacy root certificate signatures. + @note MD2 signature verification also requires + ENABLE_MD5_SIGNED_CERTS and USE_MD5. + */ +# define USE_MD2 + +/* Please enable, unless using no HMAC algorithms. */ +# define USE_HMAC + +/** + HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869). + Needed in TLS 1.3 key derivation. +*/ +# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384) +# define USE_HKDF +# endif + +/******************************************************************************/ +/** + X.509 Certificates/PKI + */ +# define USE_BASE64_DECODE +# define USE_X509/**< Enable minimal X.509 support. */ +# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ +# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ +/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ +# define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD +/**< Support extra distinguished name attributes not mentioned in RFC 5280. */ +# define USE_EXTRA_DN_ATTRIBUTES +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ +/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ +# define ENABLE_MD5_SIGNED_CERTS/** @security Accept MD5 signed certs? */ + +/** + @security SHA-1 based signatures are insecure, as SHA-1 can no longer + be considered collision resistant (https://shattered.it/static/shattered.pdf). + Enable if compatibility with old certificates is required. + */ +# define ENABLE_SHA1_SIGNED_CERTS + +/**< @security Allow parsing of locally trusted v1 root certs? */ +# define ALLOW_VERSION_1_ROOT_CERT_PARSE +/** + When parsing certificates, always also retain the unparsed DER data. + Enabling this has the same effect as setting the + CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call. + */ +# define ALWAYS_KEEP_CERT_DER +/** + Always attempt to match expectedName with the subject CN, even if + a supported, but non-matching subjectAltName was presented. + The default behaviour is to check the CN only when no supported SAN + was presented, in accordance with Section 6.4.4 of RFC 6125. + */ +/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */ +# define USE_CRL/***< @pre USE_FULL_CERT_PARSE */ +# ifdef USE_CRL +/** + Allow CRL authentication to succeed even when signer CA's cert does not + have the keyUsage extension and thus no cRLSign bit. + Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension + and the cRLSign bit. + */ +# define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE +# endif +/** + Enable OCSP response and request handling. +*/ +# define USE_OCSP/**< @pre USE_SHA1 */ +# ifdef USE_OCSP +# define USE_OCSP_RESPONSE +# elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) +/** + Enable parsing and writing of OCSP responses. This is enough + to support OCSP stapling. +*/ +# define USE_OCSP_RESPONSE/**< @pre USE_SHA1 */ +#endif /* USE_OCSP */ + +/******************************************************************************/ +/** + Various PKCS standards support + */ +# define USE_PRIVATE_KEY_PARSING +# define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */ +/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */ +# define USE_PBKDF1 +# define USE_PKCS8/* Alternative private key storage format */ +# define USE_PKCS12/**< @pre USE_PKCS8 */ +# define USE_PKCS1_OAEP/* OAEP padding algorithm */ +# define USE_PKCS1_PSS/* PSS padding algorithm */ + +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +# define USE_BASE64_DECODE/* Allow decoding Base64-encoded data. */ +# define USE_PEM_DECODE/* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + +#endif /* _h_PS_CRYPTOCONFIG */ + +/******************************************************************************/ diff --git a/configs/fulltest/matrixsslConfig.h b/configs/fulltest/matrixsslConfig.h new file mode 100644 index 0000000..d26f9dc --- /dev/null +++ b/configs/fulltest/matrixsslConfig.h @@ -0,0 +1,447 @@ +/** + * @file matrixsslConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for building the MatrixSSL library. + * This configuration is intended to be used in FIPS Mode of operation. + * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and + * to enable the most commonly used cipher suites. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSLCONFIG +# define _h_MATRIXSSLCONFIG + +# ifdef __cplusplus +extern "C" { +# endif + +/** + NIST SP 800-52 Rev 1 Conformance. + Guidelines for the Selection, Configuration, and Use of Transport Layer + Security (TLS) Implementations + The key words "shall", "shall not", "should", "should not" and "may" + are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as + "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility + is not relevant. + @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf + */ + +/******************************************************************************/ +/** + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. + */ +/* #define USE_SSL_HANDSHAKE_MSG_TRACE */ + +/** + Informational trace that could help pinpoint problems with TLS/DTLS + connections. + */ +/* #define USE_SSL_INFORMATIONAL_TRACE */ +/* #define USE_DTLS_DEBUG_TRACE */ + +/******************************************************************************/ +/** + Recommended cipher suites. + Define the following to enable various cipher suites + At least one of these must be defined. If multiple are defined, + the handshake negotiation will determine which is best for the connection. + @note Ephemeral ciphersuites offer perfect forward security (PFS) + at the cost of a slower TLS handshake. + */ + +/** TLS 1.3 ciphers */ +# define USE_TLS_AES_128_GCM_SHA256 +# define USE_TLS_AES_256_GCM_SHA384 +# define USE_TLS_CHACHA20_POLY1305_SHA256 + +/** Ephemeral ECC DH keys, ECC DSA certificates */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +# define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + +/** Ephemeral ECC DH keys, RSA certificates */ +# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA +/* TLS 1.2 ciphers */ +# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */ +# define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +# define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +# define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA +# define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA +/* TLS 1.2 ciphers */ +# define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 +# define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 +# define USE_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + +/** Non-Ephemeral RSA keys/certificates */ +# define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */ +# define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */ +/* TLS 1.2 ciphers */ +# define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */ +# define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */ +# define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */ +# define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + These cipher suites are secure, but not widely deployed. + */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +# define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA + +/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */ +# define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */ +# define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */ + +/** Ephemeral ECC DH keys, RSA certificates */ +# define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA/**< @security NIST_SHOULD */ + +/** Pre-Shared Key Ciphers. + NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary + See NIST SP 800-52 Rev 1 Appendix C */ +# define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */ +# define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */ +/* TLS 1.2 ciphers */ +# define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */ +# define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */ + +/** Non-Ephemeral ECC DH keys, ECC DSA certificates */ +# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_MAY */ +# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */ +# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */ +# define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_MAY */ +# define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_MAY */ + +/** Non-Ephemeral ECC DH keys, RSA certificates */ +# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA +# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA +/* TLS 1.2 ciphers */ +# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 +# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 +# define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 +# define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + +/** Non-Ephemeral RSA keys/certificates */ +# define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA/**< @security NIST_SHALL */ + +/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52 + Rev 1 are not supported by the MatrixSSL / MatrixDTLS. + ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (NIST SP 800-52 Rev 1 "should") + is rarely used cipher suite and is not supported. + Also (NIST SP 800-52 Rev 1 "may") TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be + enabled as they are not supported. */ + +/******************************************************************************/ +/** + Legacy cipher suites. + These cipher suites have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher suites below need to disabled according to RFC 7465. +*/ +/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */ + +/******************************************************************************/ +/** + Ephemeral key cache support. + If not using cache, new key exchange keys are created for each TLS session. + If using cache, keys are generated initially, and re-used in each + subsequent TLS connection within a given time frame and usage count. + @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE + + @security Do not cache Ephemeral ECC keys as it is against some standards, + including NIST SP 800-56A, when in FIPS 140-2 mode of operation. + */ +/* #define NO_ECC_EPHEMERAL_CACHE *//**< @security NIST_SHALL */ + +/******************************************************************************/ +/** + Configure Support for TLS protocol versions. + Define one of: + USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3) + USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3) + USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3) + @note There is no option for enabling SSL3.0 at this level + */ +/* #define USE_TLS_1_1_AND_ABOVE *//**< @security default 1_1_AND_ABOVE */ +/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */ +# define USE_TLS_1_0_AND_ABOVE/**< @security no longer recommended. */ + +/** Enable support for session resumption in TLS 1.3. */ +# define USE_TLS_1_3_RESUMPTION + +/** TLS 1.3 code has not yet been footprint-optimized. For this reason, + it is possible to separately leave all TLS 1.3 code out of the build + by enabling this. */ +/* #define DISABLE_TLS_1_3 */ + +/******************************************************************************/ +/** + Datagram TLS support. + Enables DTLS in addition to TLS. + @pre TLS_1_1 + */ +# define USE_DTLS + +/******************************************************************************/ +/** + Compile time support for server or client side SSL + */ +# define USE_CLIENT_SIDE_SSL +# define USE_SERVER_SIDE_SSL + +/******************************************************************************/ +/** + Allow the server to parse SSL 2.0 ClientHello messages even when the + server does not actually support SSL 2.0. As per RFC 5246, E.2: + + "... even TLS servers that do not support SSL 2.0 MAY accept version + 2.0 CLIENT-HELLO messages." + + This option is for compatibility with clients that support + SSL 2.0 but are ready to negotiate a higher version such as TLS 1.0. + Note that enabling this option will only allow parsing of the SSL 2.0 + ClientHellos; it will not enable support for the SSL 2.0 protocol. + Only 32-byte challenges in the SSL 2.0 ClientHello are supported. +*/ +# ifdef USE_SERVER_SIDE_SSL +# define ALLOW_SSLV2_CLIENT_HELLO_PARSE +# endif + +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +# define USE_LENIENT_TLS_RECORD_VERSION_MATCHING + +/******************************************************************************/ +/** + Client certificate authentication + */ +# define USE_CLIENT_AUTH + +# ifdef USE_CLIENT_AUTH +/** + Enable the handshake_messages signature in the CertificateVerify + protocol message to be signed using an external module. + */ +/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */ +# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING +/** + Compile an example external module that allows the + USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example + client program and sslTest. + */ +/* #define USE_EXT_EXAMPLE_MODULE */ +# endif + +/** + Enable loading of a new client certificate and private key + in response to a CertificateRequest message from a server. This feature + allows the client program to e.g. select a client certificate + whose issuer is included in the server's list of trusted CAs + that was received in the CertificateRequest message. +*/ +/* #define USE_EXT_CLIENT_CERT_KEY_LOADING */ +# endif /* USE_CLIENT_AUTH */ + +/** + Enable if the server should send an empty CertificateRequest message if + no CA files have been loaded + */ +/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */ + +/** + Enabling this define will allow the server to "downgrade" a client auth + handshake to a standard handshake if the client replies to a + CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback + will be called with a NULL cert in this case and the user can determine if + the handshake should continue in a non-client auth state. + */ +/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ + +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +#define ALLOW_CA_BUNDLE_PARTIAL_PARSE + +/******************************************************************************/ +/** + Enable the Application Layer Protocol Negotiation extension. + Servers and Clients will still have to use the required public API to + set protocols and register application callbacks to negotiate the + protocol that will be tunneled over TLS. + @see ALPN section in the developer's guide for information. + */ +/* #define USE_ALPN */ + +/******************************************************************************/ +/** + Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the + sha1 hash of each CA file to the server for help in server selection. + This extra level of define is to help isolate the SHA1 requirement + */ +/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + A client side configuration that requires a server to provide an OCSP + response if the client uses the certitificate status request extension. + The "must staple" terminology is typically associated with certificates + at the X.509 layer but it is a good description of what is being required + of the server at the TLS level. + @pre USE_OCSP_RESPONSE must be enabled at the crypto level and the client + application must use the OCSPstapling session option at run time for this + setting to have any effect + */ +# ifdef USE_OCSP_RESPONSE +# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */ +# endif + +/******************************************************************************/ +/** + Rehandshaking support. + + Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the + protocol defined in RFC 5748 which fixed a critical exploit in + the standard TLS specification. + + @security Looking towards TLS 1.3, which removes re-handshaking, this + feature is disabled by default. + */ +# define USE_REHANDSHAKING + +/******************************************************************************//** + False Start support for Chrome and Firefox browsers. + @see https://tools.ietf.org/html/rfc7918 + + Some versions of Firefox browser and Chrome browser include support for + False Start. This flag will enable server side support on MatrixSSL + operating as server for client using false start feature. + + @note April 2012: Google has announced this feature will be removed in + version 20 of their browser due to industry compatibility issues. + However because there are other browsers using the feature, this feature + is often recommendable to enable for maximal browser compatibility. + */ +# define USE_SERVER_SIDE_FALSE_START_SUPPORT + +/******************************************************************************/ +/** + If SERVER you may define the number of sessions to cache and how + long a session will remain valid in the cache from first access. + Session caching enables very fast "session resumption handshakes". + + SSL_SESSION_TABLE_SIZE minimum value is 1 + SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0 + + @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0 + however, this will also immediately expire SESSION_TICKETS below. + */ +# ifdef USE_SERVER_SIDE_SSL +# define SSL_SESSION_TABLE_SIZE 32 +# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */ +# endif + +/******************************************************************************/ +/** + Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE + define applies to this method as well as the standard method. The + SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list. + */ +# define USE_STATELESS_SESSION_TICKETS +# define SSL_SESSION_TICKET_LIST_LEN 32 + +/******************************************************************************/ +/** + The initial buffer sizes for send and receive buffers in each ssl_t session. + Buffers are internally grown if more incoming or outgoing data storage is + needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the + buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced + to this size. Most standard SSL handshakes require on the order of 1024 B. + + SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE + */ +# ifndef USE_DTLS +# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */ +# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */ +# else +/******************************************************************************/ +/** + The Path Maximum Transmission Unit is the largest datagram that can be + sent or recieved. It is beyond the scope of DTLS to negotiate this value + so make sure both sides have agreed on this value. This is an enforced + limitation in MatrixDTLS so connections will not succeed if a peer has a + PTMU set larger than this value. + */ +# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */ +# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ +# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ + +/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ +# endif + +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + +# ifdef __cplusplus +} +# endif + +#endif /* _h_MATRIXCONFIG */ +/******************************************************************************/ diff --git a/configs/noecc/coreConfig.h b/configs/noecc/coreConfig.h index a0e9380..0255323 100644 --- a/configs/noecc/coreConfig.h +++ b/configs/noecc/coreConfig.h @@ -40,61 +40,10 @@ /* Debug and tracing configuration */ /******************************************************************************/ -/** - Select tracing facility. - Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and - allows log redirection. - - On the smallest embedded targets platform using PS_NO_LOGF may provide - footprint benefits but will limit logging capabilities. - */ - -/* Uncomment to use previous generation logging facility: */ -/* #define PS_NO_LOGF */ - -/* When using psLogf, logging messages by default go to the binary, but - they are not shown unless enabled by environment variables or - filter loaded with psLogfSetHookEnabledCheck() function. - - Enable macros below to completely remove specified logging class. */ -/* #define PS_NO_LOGF_FATAL */ -/* #define PS_NO_LOGF_ERROR */ -/* #define PS_NO_LOGF_WARNING */ -/* #define PS_NO_LOGF_INFO */ -/* #define PS_NO_LOGF_VERBOSE */ -/* #define PS_NO_LOGF_DEBUG */ -/* #define PS_NO_LOGF_TRACE */ -/* #define PS_NO_LOGF_CALL_TRACE */ - -/* MatrixSSL contains extensive tracing capabilities. The lines below - disable trace and call trace message levels, unless debug build. - Omitting the messages will improve performance and create smaller - executables with a degradation in debugging capabilities. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_TRACE -# define PS_NO_LOGF_TRACE -# endif -# ifndef PS_NO_LOGF_CALL_TRACE -# define PS_NO_LOGF_CALL_TRACE -# endif -# endif - -/* File and line information consumes some storage and may reveal details on - structure of software. This information is omitted from production builds, - but included within "debug build". If you want to include file and line - information also on production builds, disable the lines below. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_FILELINE -# define PS_NO_LOGF_FILELINE -# endif -# endif - /** Enable various levels of trace. When these option is turned off, messages are silently discarded and their text does not take space in the binary image. - Note: These are legacy configuration, and it is recommended to use - PS_NO_LOGF_* above, unless PS_NO_LOGF is set. */ /* #define USE_CORE_TRACE */ # ifndef NO_CORE_ERROR @@ -104,6 +53,16 @@ # define USE_CORE_ASSERT # endif +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + /******************************************************************************/ /* Other Configurable features */ /******************************************************************************/ @@ -116,6 +75,11 @@ /* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ # endif +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +/* #define NO_FILE_SYSTEM */ + /** Include the psCoreOsdepMutex family of APIs diff --git a/configs/noecc/cryptoConfig.h b/configs/noecc/cryptoConfig.h index 032a814..dfdf7c9 100644 --- a/configs/noecc/cryptoConfig.h +++ b/configs/noecc/cryptoConfig.h @@ -228,10 +228,14 @@ # define USE_X509/**< Enable minimal X.509 support. */ # define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ # define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ /**< Support extra distinguished name attributes not mentioned in RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ /* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ /* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ @@ -273,13 +277,12 @@ /* #define USE_OCSP *//**< @pre USE_SHA1 */ # ifdef USE_OCSP # define USE_OCSP_RESPONSE -# define USE_OCSP_REQUEST # elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) /** Enable parsing and writing of OCSP responses. This is enough to support OCSP stapling. */ -# define USE_OCSP_RESPONSE /**< @pre USE_SHA1 */ +# define USE_OCSP_RESPONSE/**< @pre USE_SHA1 */ #endif /* USE_OCSP */ /******************************************************************************/ @@ -295,6 +298,12 @@ # define USE_PKCS1_OAEP/* OAEP padding algorithm */ # define USE_PKCS1_PSS/* PSS padding algorithm */ +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +# define USE_BASE64_DECODE/* Allow decoding Base64-encoded data. */ +# define USE_PEM_DECODE/* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + #endif /* _h_PS_CRYPTOCONFIG */ /******************************************************************************/ diff --git a/configs/noecc/matrixsslConfig.h b/configs/noecc/matrixsslConfig.h index 1268ea1..1f91657 100644 --- a/configs/noecc/matrixsslConfig.h +++ b/configs/noecc/matrixsslConfig.h @@ -55,12 +55,14 @@ extern "C" { /******************************************************************************/ /** - Show which SSL messages are created and parsed + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. */ /* #define USE_SSL_HANDSHAKE_MSG_TRACE */ /** - Informational trace that could help pinpoint problems with SSL connections + Informational trace that could help pinpoint problems with TLS/DTLS + connections. */ /* #define USE_SSL_INFORMATIONAL_TRACE */ /* #define USE_DTLS_DEBUG_TRACE */ @@ -250,6 +252,14 @@ extern "C" { /* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ # endif +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + /******************************************************************************/ /** Client certificate authentication @@ -424,6 +434,11 @@ extern "C" { /* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ # endif +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + # ifdef __cplusplus } # endif diff --git a/configs/psk/coreConfig.h b/configs/psk/coreConfig.h index edd7dfe..e8b397f 100644 --- a/configs/psk/coreConfig.h +++ b/configs/psk/coreConfig.h @@ -40,61 +40,10 @@ /* Debug and tracing configuration */ /******************************************************************************/ -/** - Select tracing facility. - Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and - allows log redirection. - - On the smallest embedded targets platform using PS_NO_LOGF may provide - footprint benefits but will limit logging capabilities. - */ - -/* Uncomment to use previous generation logging facility: */ -/* #define PS_NO_LOGF */ - -/* When using psLogf, logging messages by default go to the binary, but - they are not shown unless enabled by environment variables or - filter loaded with psLogfSetHookEnabledCheck() function. - - Enable macros below to completely remove specified logging class. */ -/* #define PS_NO_LOGF_FATAL */ -/* #define PS_NO_LOGF_ERROR */ -/* #define PS_NO_LOGF_WARNING */ -/* #define PS_NO_LOGF_INFO */ -/* #define PS_NO_LOGF_VERBOSE */ -/* #define PS_NO_LOGF_DEBUG */ -/* #define PS_NO_LOGF_TRACE */ -/* #define PS_NO_LOGF_CALL_TRACE */ - -/* MatrixSSL contains extensive tracing capabilities. The lines below - disable trace and call trace message levels, unless debug build. - Omitting the messages will improve performance and create smaller - executables with a degradation in debugging capabilities. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_TRACE -# define PS_NO_LOGF_TRACE -# endif -# ifndef PS_NO_LOGF_CALL_TRACE -# define PS_NO_LOGF_CALL_TRACE -# endif -# endif - -/* File and line information consumes some storage and may reveal details on - structure of software. This information is omitted from production builds, - but included within "debug build". If you want to include file and line - information also on production builds, disable the lines below. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_FILELINE -# define PS_NO_LOGF_FILELINE -# endif -# endif - /** Enable various levels of trace. When these option is turned off, messages are silently discarded and their text does not take space in the binary image. - Note: These are legacy configuration, and it is recommended to use - PS_NO_LOGF_* above, unless PS_NO_LOGF is set. */ /* #define USE_CORE_TRACE */ # ifndef NO_CORE_ERROR @@ -104,6 +53,16 @@ # define USE_CORE_ASSERT # endif +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + /******************************************************************************/ /* Other Configurable features */ /******************************************************************************/ @@ -116,6 +75,11 @@ /* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ # endif +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +/* #define NO_FILE_SYSTEM */ + /** Include the psCoreOsdepMutex family of APIs diff --git a/configs/psk/cryptoConfig.h b/configs/psk/cryptoConfig.h index 11798ec..f4a83a4 100644 --- a/configs/psk/cryptoConfig.h +++ b/configs/psk/cryptoConfig.h @@ -228,10 +228,14 @@ /* #define USE_X509 *//**< Enable minimal X.509 support. */ /* #define USE_CERT_PARSE *//**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ /* #define USE_FULL_CERT_PARSE *//**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ /**< Support extra distinguished name attributes not mentioned in RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ /* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ /* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ @@ -273,13 +277,12 @@ /* #define USE_OCSP *//**< @pre USE_SHA1 */ # ifdef USE_OCSP # define USE_OCSP_RESPONSE -# define USE_OCSP_REQUEST # elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) /** Enable parsing and writing of OCSP responses. This is enough to support OCSP stapling. */ -# define USE_OCSP_RESPONSE /**< @pre USE_SHA1 */ +/* #define USE_OCSP_RESPONSE *//**< @pre USE_SHA1 */ #endif /* USE_OCSP */ /******************************************************************************/ @@ -295,6 +298,12 @@ /* #define USE_PKCS1_OAEP *//* OAEP padding algorithm */ /* #define USE_PKCS1_PSS *//* PSS padding algorithm */ +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +/* #define USE_BASE64_DECODE *//* Allow decoding Base64-encoded data. */ +/* #define USE_PEM_DECODE *//* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + #endif /* _h_PS_CRYPTOCONFIG */ /******************************************************************************/ diff --git a/configs/psk/matrixsslConfig.h b/configs/psk/matrixsslConfig.h index b7cf2ed..6d60c57 100644 --- a/configs/psk/matrixsslConfig.h +++ b/configs/psk/matrixsslConfig.h @@ -55,12 +55,14 @@ extern "C" { /******************************************************************************/ /** - Show which SSL messages are created and parsed + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. */ /* #define USE_SSL_HANDSHAKE_MSG_TRACE */ /** - Informational trace that could help pinpoint problems with SSL connections + Informational trace that could help pinpoint problems with TLS/DTLS + connections. */ /* #define USE_SSL_INFORMATIONAL_TRACE */ /* #define USE_DTLS_DEBUG_TRACE */ @@ -250,6 +252,14 @@ extern "C" { /* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ # endif +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + /******************************************************************************/ /** Client certificate authentication @@ -424,6 +434,11 @@ extern "C" { /* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ # endif +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + # ifdef __cplusplus } # endif diff --git a/configs/rsaonly/coreConfig.h b/configs/rsaonly/coreConfig.h index a0e9380..0255323 100644 --- a/configs/rsaonly/coreConfig.h +++ b/configs/rsaonly/coreConfig.h @@ -40,61 +40,10 @@ /* Debug and tracing configuration */ /******************************************************************************/ -/** - Select tracing facility. - Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and - allows log redirection. - - On the smallest embedded targets platform using PS_NO_LOGF may provide - footprint benefits but will limit logging capabilities. - */ - -/* Uncomment to use previous generation logging facility: */ -/* #define PS_NO_LOGF */ - -/* When using psLogf, logging messages by default go to the binary, but - they are not shown unless enabled by environment variables or - filter loaded with psLogfSetHookEnabledCheck() function. - - Enable macros below to completely remove specified logging class. */ -/* #define PS_NO_LOGF_FATAL */ -/* #define PS_NO_LOGF_ERROR */ -/* #define PS_NO_LOGF_WARNING */ -/* #define PS_NO_LOGF_INFO */ -/* #define PS_NO_LOGF_VERBOSE */ -/* #define PS_NO_LOGF_DEBUG */ -/* #define PS_NO_LOGF_TRACE */ -/* #define PS_NO_LOGF_CALL_TRACE */ - -/* MatrixSSL contains extensive tracing capabilities. The lines below - disable trace and call trace message levels, unless debug build. - Omitting the messages will improve performance and create smaller - executables with a degradation in debugging capabilities. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_TRACE -# define PS_NO_LOGF_TRACE -# endif -# ifndef PS_NO_LOGF_CALL_TRACE -# define PS_NO_LOGF_CALL_TRACE -# endif -# endif - -/* File and line information consumes some storage and may reveal details on - structure of software. This information is omitted from production builds, - but included within "debug build". If you want to include file and line - information also on production builds, disable the lines below. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_FILELINE -# define PS_NO_LOGF_FILELINE -# endif -# endif - /** Enable various levels of trace. When these option is turned off, messages are silently discarded and their text does not take space in the binary image. - Note: These are legacy configuration, and it is recommended to use - PS_NO_LOGF_* above, unless PS_NO_LOGF is set. */ /* #define USE_CORE_TRACE */ # ifndef NO_CORE_ERROR @@ -104,6 +53,16 @@ # define USE_CORE_ASSERT # endif +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + /******************************************************************************/ /* Other Configurable features */ /******************************************************************************/ @@ -116,6 +75,11 @@ /* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ # endif +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +/* #define NO_FILE_SYSTEM */ + /** Include the psCoreOsdepMutex family of APIs diff --git a/configs/rsaonly/cryptoConfig.h b/configs/rsaonly/cryptoConfig.h index 7066a93..0487d5c 100644 --- a/configs/rsaonly/cryptoConfig.h +++ b/configs/rsaonly/cryptoConfig.h @@ -228,10 +228,14 @@ # define USE_X509/**< Enable minimal X.509 support. */ # define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ # define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ /**< Support extra distinguished name attributes not mentioned in RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ /* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ /* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ @@ -273,13 +277,12 @@ /* #define USE_OCSP *//**< @pre USE_SHA1 */ # ifdef USE_OCSP # define USE_OCSP_RESPONSE -# define USE_OCSP_REQUEST # elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) /** Enable parsing and writing of OCSP responses. This is enough to support OCSP stapling. */ -# define USE_OCSP_RESPONSE /**< @pre USE_SHA1 */ +# define USE_OCSP_RESPONSE/**< @pre USE_SHA1 */ #endif /* USE_OCSP */ /******************************************************************************/ @@ -295,6 +298,12 @@ # define USE_PKCS1_OAEP/* OAEP padding algorithm */ # define USE_PKCS1_PSS/* PSS padding algorithm */ +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +# define USE_BASE64_DECODE/* Allow decoding Base64-encoded data. */ +# define USE_PEM_DECODE/* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + #endif /* _h_PS_CRYPTOCONFIG */ /******************************************************************************/ diff --git a/configs/rsaonly/matrixsslConfig.h b/configs/rsaonly/matrixsslConfig.h index 303a1b7..026a254 100644 --- a/configs/rsaonly/matrixsslConfig.h +++ b/configs/rsaonly/matrixsslConfig.h @@ -55,12 +55,14 @@ extern "C" { /******************************************************************************/ /** - Show which SSL messages are created and parsed + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. */ /* #define USE_SSL_HANDSHAKE_MSG_TRACE */ /** - Informational trace that could help pinpoint problems with SSL connections + Informational trace that could help pinpoint problems with TLS/DTLS + connections. */ /* #define USE_SSL_INFORMATIONAL_TRACE */ /* #define USE_DTLS_DEBUG_TRACE */ @@ -250,6 +252,14 @@ extern "C" { /* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ # endif +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + /******************************************************************************/ /** Client certificate authentication @@ -424,6 +434,11 @@ extern "C" { /* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ # endif +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + # ifdef __cplusplus } # endif diff --git a/configs/tls/coreConfig.h b/configs/tls/coreConfig.h index a0e9380..0255323 100644 --- a/configs/tls/coreConfig.h +++ b/configs/tls/coreConfig.h @@ -40,61 +40,10 @@ /* Debug and tracing configuration */ /******************************************************************************/ -/** - Select tracing facility. - Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and - allows log redirection. - - On the smallest embedded targets platform using PS_NO_LOGF may provide - footprint benefits but will limit logging capabilities. - */ - -/* Uncomment to use previous generation logging facility: */ -/* #define PS_NO_LOGF */ - -/* When using psLogf, logging messages by default go to the binary, but - they are not shown unless enabled by environment variables or - filter loaded with psLogfSetHookEnabledCheck() function. - - Enable macros below to completely remove specified logging class. */ -/* #define PS_NO_LOGF_FATAL */ -/* #define PS_NO_LOGF_ERROR */ -/* #define PS_NO_LOGF_WARNING */ -/* #define PS_NO_LOGF_INFO */ -/* #define PS_NO_LOGF_VERBOSE */ -/* #define PS_NO_LOGF_DEBUG */ -/* #define PS_NO_LOGF_TRACE */ -/* #define PS_NO_LOGF_CALL_TRACE */ - -/* MatrixSSL contains extensive tracing capabilities. The lines below - disable trace and call trace message levels, unless debug build. - Omitting the messages will improve performance and create smaller - executables with a degradation in debugging capabilities. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_TRACE -# define PS_NO_LOGF_TRACE -# endif -# ifndef PS_NO_LOGF_CALL_TRACE -# define PS_NO_LOGF_CALL_TRACE -# endif -# endif - -/* File and line information consumes some storage and may reveal details on - structure of software. This information is omitted from production builds, - but included within "debug build". If you want to include file and line - information also on production builds, disable the lines below. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_FILELINE -# define PS_NO_LOGF_FILELINE -# endif -# endif - /** Enable various levels of trace. When these option is turned off, messages are silently discarded and their text does not take space in the binary image. - Note: These are legacy configuration, and it is recommended to use - PS_NO_LOGF_* above, unless PS_NO_LOGF is set. */ /* #define USE_CORE_TRACE */ # ifndef NO_CORE_ERROR @@ -104,6 +53,16 @@ # define USE_CORE_ASSERT # endif +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + /******************************************************************************/ /* Other Configurable features */ /******************************************************************************/ @@ -116,6 +75,11 @@ /* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ # endif +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +/* #define NO_FILE_SYSTEM */ + /** Include the psCoreOsdepMutex family of APIs diff --git a/configs/tls/cryptoConfig.h b/configs/tls/cryptoConfig.h index 13fee06..8ecd356 100644 --- a/configs/tls/cryptoConfig.h +++ b/configs/tls/cryptoConfig.h @@ -228,10 +228,14 @@ # define USE_X509/**< Enable minimal X.509 support. */ # define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ # define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ /**< Support extra distinguished name attributes not mentioned in RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ /* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ /* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ @@ -273,13 +277,12 @@ /* #define USE_OCSP *//**< @pre USE_SHA1 */ # ifdef USE_OCSP # define USE_OCSP_RESPONSE -# define USE_OCSP_REQUEST # elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) /** Enable parsing and writing of OCSP responses. This is enough to support OCSP stapling. */ -# define USE_OCSP_RESPONSE /**< @pre USE_SHA1 */ +# define USE_OCSP_RESPONSE/**< @pre USE_SHA1 */ #endif /* USE_OCSP */ /******************************************************************************/ @@ -295,6 +298,12 @@ # define USE_PKCS1_OAEP/* OAEP padding algorithm */ # define USE_PKCS1_PSS/* PSS padding algorithm */ +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +# define USE_BASE64_DECODE/* Allow decoding Base64-encoded data. */ +# define USE_PEM_DECODE/* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + #endif /* _h_PS_CRYPTOCONFIG */ /******************************************************************************/ diff --git a/configs/tls/matrixsslConfig.h b/configs/tls/matrixsslConfig.h index 6c7cea3..f39c60c 100644 --- a/configs/tls/matrixsslConfig.h +++ b/configs/tls/matrixsslConfig.h @@ -55,12 +55,14 @@ extern "C" { /******************************************************************************/ /** - Show which SSL messages are created and parsed + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. */ /* #define USE_SSL_HANDSHAKE_MSG_TRACE */ /** - Informational trace that could help pinpoint problems with SSL connections + Informational trace that could help pinpoint problems with TLS/DTLS + connections. */ /* #define USE_SSL_INFORMATIONAL_TRACE */ /* #define USE_DTLS_DEBUG_TRACE */ @@ -250,6 +252,14 @@ extern "C" { /* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ # endif +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + /******************************************************************************/ /** Client certificate authentication @@ -424,6 +434,11 @@ extern "C" { /* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ # endif +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + # ifdef __cplusplus } # endif diff --git a/configs/tls12-minimal-client-ecc/coreConfig.h b/configs/tls12-minimal-client-ecc/coreConfig.h new file mode 100644 index 0000000..5c39747 --- /dev/null +++ b/configs/tls12-minimal-client-ecc/coreConfig.h @@ -0,0 +1,109 @@ +/** + * @file coreConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for Matrix core module. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CORECONFIG +# define _h_PS_CORECONFIG + + +/******************************************************************************/ +/* Debug and tracing configuration */ +/******************************************************************************/ + +/** + Enable various levels of trace. + When these option is turned off, messages are silently + discarded and their text does not take space in the binary image. + */ +/* #define USE_CORE_TRACE */ +# ifndef NO_CORE_ERROR +# define USE_CORE_ERROR +# endif +# ifndef NO_CORE_ASSERT +# define USE_CORE_ASSERT +# endif + +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + +/******************************************************************************/ +/* Other Configurable features */ +/******************************************************************************/ + +/** + If enabled, calls to the psError set of APIs will perform a platform + abort on the exeutable to aid in debugging. + */ +# ifdef DEBUG +/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ +# endif + +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +# define NO_FILE_SYSTEM + +/** + Include the psCoreOsdepMutex family of APIs + + @note If intending to compile crypto-cl, then this flag should + always be set. +*/ +# ifndef NO_MULTITHREADING +/* #define USE_MULTITHREADING */ +# endif /* NO_MULTITHREADING */ + +/** + Include the psNetwork family of APIs. + + These APIs allow simple high-level socket api. + The API derive from BSD Sockets, and therefore it can only be used + on devices which have the prerequisitive APIs. + MatrixSSL itself can be used also be used without PS networking, but + many of example programs and MatrixSSLNet are based on PS networking. + */ +# ifndef NO_PS_NETWORKING +# define USE_PS_NETWORKING +# endif /* NO_PS_NETWORKING */ + +#endif /* _h_PS_CORECONFIG */ + +/******************************************************************************/ + diff --git a/configs/tls12-minimal-client-ecc/cryptoConfig.h b/configs/tls12-minimal-client-ecc/cryptoConfig.h new file mode 100644 index 0000000..03ff8e8 --- /dev/null +++ b/configs/tls12-minimal-client-ecc/cryptoConfig.h @@ -0,0 +1,309 @@ +/** + * @file cryptoConfig.h + * @version $Format:%h%d$ + * + * Configuration file for crypto features. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CRYPTOCONFIG +# define _h_PS_CRYPTOCONFIG + +/******************************************************************************/ +/* Configurable features */ +/******************************************************************************/ +/** + Define to enable psTrace*Crypto APIs for debugging the crypto module. + */ +/* #define USE_CRYPTO_TRACE */ + +# ifdef DEBUG +/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */ +# endif + +/******************************************************************************/ +/* + Use built-in cryptographic library delivered with MatrixSSL + */ +# define USE_NATIVE_RSA /* Default built-in software support */ + +/******************************************************************************/ +/** + Security related settings. + + @security MIN_*_BITS is the minimum supported key sizes in bits, weaker + keys will be rejected. + */ +# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */ + +# define MIN_RSA_BITS 1024 + +/* The configuration can define set minimum for RSA public exponent. + + For CL crypto, the default is 65537 (according to FIPS 186-4 standard). + It can be overridden on line below: + */ +/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */ + +# define MIN_DH_BITS 1024 + +# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */ + +/******************************************************************************/ +/** + Public-Key Algorithm Support. + */ +/* #define USE_RSA */ +# define USE_ECC +/* #define USE_DH */ +/**< @note Enable verification of DSA signatures in certificate validation. + Works only when using the CL/SL library. @pre USE_CERT_PARSE. */ +/* #define USE_DSA_VERIFY */ +# ifdef USE_DH +/**< @note Enable this if you intent to support Diffie-Hellman groups larger + than 4096. Usually such large groups are not used. */ +/* #define USE_LARGE_DH_GROUPS */ +# endif /* USE_DH */ +/**< @note Enable ECDHE with Curve25519. */ +/* #define USE_X25519 */ +/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures. + @pre USE_ECC, USE_SHA512. */ +/* #define USE_ED25519 */ + +/******************************************************************************/ +/** + Build the PKCS and ASN1 extra CL sublibraries. + These are needed by the CL_PKCS API. + */ + +/******************************************************************************/ + +/** + Define to enable the individual NIST Prime curves. + @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +# ifdef USE_ECC +/* #define USE_SECP192R1 *//**< @security FIPS allowed for sig ver only. */ +/* #define USE_SECP224R1 */ +# define USE_SECP256R1/**< @security NIST_SHALL */ +# define USE_SECP384R1/**< @security NIST_SHALL */ +# define USE_SECP521R1 +# endif + +/** + Define to enable the individual Brainpool curves. + @see https://tools.ietf.org/html/rfc5639 + @security WARNING: Public points on Brainpool curves are not validated + */ +# ifdef USE_ECC +/* #define USE_BRAIN224R1 */ +/* #define USE_BRAIN256R1 */ +/* #define USE_BRAIN384R1 */ +/* #define USE_BRAIN512R1 */ +# endif + +/******************************************************************************/ +/** + Symmetric and AEAD ciphers. + @security Deprecated ciphers must be enabled in cryptolib.h + */ +/* #define USE_AES *//* Enable/Disable AES */ +/* #define USE_AES_CBC */ +# define USE_AES_GCM + +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ +/* #define USE_CHACHA20_POLY1305_IETF */ + +/** @security 3DES is still relatively secure, however is deprecated for TLS */ +/* #define USE_3DES */ + +/******************************************************************************/ +/** + Legacy ciphers. + These ciphers have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher below need to disabled according to RFC 7465. +*/ +/* #define USE_ARC4 */ + +/******************************************************************************/ +/** + Digest algorithms. + + @note SHA256 and above are used with TLS 1.2, and also used for + certificate signatures on some certificates regardless of TLS version. + + @security MD5 is deprecated, but still required in combination with SHA-1 + for TLS handshakes before TLS 1.2, meaning that the strength is at least + that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable + MD5 only for this purpose. The only other usage of MD5 by TLS is for + certificate signatures and MD5 based cipher suites. Both of which are + disabled at compile time by default. + + @security SHA1 will be deprecated in the future, but is still required in + combination with MD5 for versions prior to TLS 1.2. In addition, SHA1 + certificates are still commonly used, so SHA1 support may be needed + to validate older certificates. It is possible to completely disable + SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting + only with newer certificates. + */ +/* #define USE_SHA224 *//**< @note Used only for cert signature */ +# define USE_SHA256/**< @note Required for TLS 1.2 and above */ +# define USE_HMAC_SHA256 +# define USE_SHA384/**< @pre USE_SHA512 */ +# define USE_HMAC_SHA384 +# define USE_SHA512 + +/** + @security SHA-1 based hashes are deprecated but enabled by default + @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_SHA1 */ +/* #define USE_HMAC_SHA1 */ + +/** + @security MD5 is considered insecure, but required by TLS < 1.2 + @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_MD5 */ +/* #define USE_MD5SHA1 *//* Required for < TLS 1.2 Handshake */ +/* #define USE_HMAC_MD5 */ + +/** + @security MD2 is considered insecure, but is sometimes used for + verification of legacy root certificate signatures. + @note MD2 signature verification also requires + ENABLE_MD5_SIGNED_CERTS and USE_MD5. + */ +/* #define USE_MD2 */ + +/* Please enable, unless using no HMAC algorithms. */ +# define USE_HMAC + +/** + HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869). + Needed in TLS 1.3 key derivation. +*/ +# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384) +# define USE_HKDF +# endif + +/******************************************************************************/ +/** + X.509 Certificates/PKI + */ +/* #define USE_BASE64_DECODE */ +# define USE_X509/**< Enable minimal X.509 support. */ +# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ +# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ +/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ +/**< Support extra distinguished name attributes not mentioned in RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ +/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ +/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ + +/** + @security SHA-1 based signatures are insecure, as SHA-1 can no longer + be considered collision resistant (https://shattered.it/static/shattered.pdf). + Enable if compatibility with old certificates is required. + */ +/* #define ENABLE_SHA1_SIGNED_CERTS */ + +/**< @security Allow parsing of locally trusted v1 root certs? */ +/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */ +/** + When parsing certificates, always also retain the unparsed DER data. + Enabling this has the same effect as setting the + CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call. + */ +/* #define ALWAYS_KEEP_CERT_DER */ +/** + Always attempt to match expectedName with the subject CN, even if + a supported, but non-matching subjectAltName was presented. + The default behaviour is to check the CN only when no supported SAN + was presented, in accordance with Section 6.4.4 of RFC 6125. + */ +/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */ +/* #define USE_CRL *//***< @pre USE_FULL_CERT_PARSE */ +# ifdef USE_CRL +/** + Allow CRL authentication to succeed even when signer CA's cert does not + have the keyUsage extension and thus no cRLSign bit. + Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension + and the cRLSign bit. + */ +/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */ +# endif +/** + Enable OCSP response and request handling. +*/ +/* #define USE_OCSP *//**< @pre USE_SHA1 */ +# ifdef USE_OCSP +# define USE_OCSP_RESPONSE +# elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) +/** + Enable parsing and writing of OCSP responses. This is enough + to support OCSP stapling. +*/ +/* #define USE_OCSP_RESPONSE *//**< @pre USE_SHA1 */ +#endif /* USE_OCSP */ + +/******************************************************************************/ +/** + Various PKCS standards support + */ +# define USE_PRIVATE_KEY_PARSING +/* #define USE_PKCS5 *//**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */ +/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */ +/* #define USE_PBKDF1 */ +/* #define USE_PKCS8 *//* Alternative private key storage format */ +/* #define USE_PKCS12 *//**< @pre USE_PKCS8 */ +/* #define USE_PKCS1_OAEP *//* OAEP padding algorithm */ +/* #define USE_PKCS1_PSS *//* PSS padding algorithm */ + +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +/* #define USE_BASE64_DECODE *//* Allow decoding Base64-encoded data. */ +/* #define USE_PEM_DECODE *//* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + +#endif /* _h_PS_CRYPTOCONFIG */ + +/******************************************************************************/ diff --git a/configs/tls12-minimal-client-ecc/matrixsslConfig.h b/configs/tls12-minimal-client-ecc/matrixsslConfig.h new file mode 100644 index 0000000..62eccb8 --- /dev/null +++ b/configs/tls12-minimal-client-ecc/matrixsslConfig.h @@ -0,0 +1,447 @@ +/** + * @file matrixsslConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for building the MatrixSSL library. + * This configuration is intended to be used in FIPS Mode of operation. + * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and + * to enable the most commonly used cipher suites. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSLCONFIG +# define _h_MATRIXSSLCONFIG + +# ifdef __cplusplus +extern "C" { +# endif + +/** + NIST SP 800-52 Rev 1 Conformance. + Guidelines for the Selection, Configuration, and Use of Transport Layer + Security (TLS) Implementations + The key words "shall", "shall not", "should", "should not" and "may" + are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as + "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility + is not relevant. + @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf + */ + +/******************************************************************************/ +/** + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. + */ +/* #define USE_SSL_HANDSHAKE_MSG_TRACE */ + +/** + Informational trace that could help pinpoint problems with TLS/DTLS + connections. + */ +/* #define USE_SSL_INFORMATIONAL_TRACE */ +/* #define USE_DTLS_DEBUG_TRACE */ + +/******************************************************************************/ +/** + Recommended cipher suites. + Define the following to enable various cipher suites + At least one of these must be defined. If multiple are defined, + the handshake negotiation will determine which is best for the connection. + @note Ephemeral ciphersuites offer perfect forward security (PFS) + at the cost of a slower TLS handshake. + */ + +/** TLS 1.3 ciphers */ +/* #define USE_TLS_AES_128_GCM_SHA256 */ +/* #define USE_TLS_AES_256_GCM_SHA384 */ +/* #define USE_TLS_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + These cipher suites are secure, but not widely deployed. + */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */ + +/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */ +/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */ + +/** Pre-Shared Key Ciphers. + NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary + See NIST SP 800-52 Rev 1 Appendix C */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA384 *//**< @security NIST_SHOULD_NOT */ + +/** Non-Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_MAY */ + +/** Non-Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */ + +/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52 + Rev 1 are not supported by the MatrixSSL / MatrixDTLS. + ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (NIST SP 800-52 Rev 1 "should") + is rarely used cipher suite and is not supported. + Also (NIST SP 800-52 Rev 1 "may") TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be + enabled as they are not supported. */ + +/******************************************************************************/ +/** + Legacy cipher suites. + These cipher suites have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher suites below need to disabled according to RFC 7465. +*/ +/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */ + +/******************************************************************************/ +/** + Ephemeral key cache support. + If not using cache, new key exchange keys are created for each TLS session. + If using cache, keys are generated initially, and re-used in each + subsequent TLS connection within a given time frame and usage count. + @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE + + @security Do not cache Ephemeral ECC keys as it is against some standards, + including NIST SP 800-56A, when in FIPS 140-2 mode of operation. + */ +# define NO_ECC_EPHEMERAL_CACHE/**< @security NIST_SHALL */ + +/******************************************************************************/ +/** + Configure Support for TLS protocol versions. + Define one of: + USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3) + USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3) + USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3) + @note There is no option for enabling SSL3.0 at this level + */ +/* #define USE_TLS_1_1_AND_ABOVE *//**< @security default 1_1_AND_ABOVE */ +# define USE_TLS_1_2_AND_ABOVE/**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */ +/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */ + +/** Enable support for session resumption in TLS 1.3. */ +/* #define USE_TLS_1_3_RESUMPTION */ + +/** TLS 1.3 code has not yet been footprint-optimized. For this reason, + it is possible to separately leave all TLS 1.3 code out of the build + by enabling this. */ +# define DISABLE_TLS_1_3 + +/******************************************************************************/ +/** + Datagram TLS support. + Enables DTLS in addition to TLS. + @pre TLS_1_1 + */ +/* #define USE_DTLS */ + +/******************************************************************************/ +/** + Compile time support for server or client side SSL + */ +# define USE_CLIENT_SIDE_SSL +/* #define USE_SERVER_SIDE_SSL */ + +/******************************************************************************/ +/** + Allow the server to parse SSL 2.0 ClientHello messages even when the + server does not actually support SSL 2.0. As per RFC 5246, E.2: + + "... even TLS servers that do not support SSL 2.0 MAY accept version + 2.0 CLIENT-HELLO messages." + + This option is for compatibility with clients that support + SSL 2.0 but are ready to negotiate a higher version such as TLS 1.0. + Note that enabling this option will only allow parsing of the SSL 2.0 + ClientHellos; it will not enable support for the SSL 2.0 protocol. + Only 32-byte challenges in the SSL 2.0 ClientHello are supported. +*/ +# ifdef USE_SERVER_SIDE_SSL +/* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ +# endif + +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + +/******************************************************************************/ +/** + Client certificate authentication + */ +# define USE_CLIENT_AUTH + +# ifdef USE_CLIENT_AUTH +/** + Enable the handshake_messages signature in the CertificateVerify + protocol message to be signed using an external module. + */ +/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */ +# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING +/** + Compile an example external module that allows the + USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example + client program and sslTest. + */ +/* #define USE_EXT_EXAMPLE_MODULE */ +# endif + +/** + Enable loading of a new client certificate and private key + in response to a CertificateRequest message from a server. This feature + allows the client program to e.g. select a client certificate + whose issuer is included in the server's list of trusted CAs + that was received in the CertificateRequest message. +*/ +/* #define USE_EXT_CLIENT_CERT_KEY_LOADING */ +# endif /* USE_CLIENT_AUTH */ + +/** + Enable if the server should send an empty CertificateRequest message if + no CA files have been loaded + */ +/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */ + +/** + Enabling this define will allow the server to "downgrade" a client auth + handshake to a standard handshake if the client replies to a + CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback + will be called with a NULL cert in this case and the user can determine if + the handshake should continue in a non-client auth state. + */ +/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ + +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + +/******************************************************************************/ +/** + Enable the Application Layer Protocol Negotiation extension. + Servers and Clients will still have to use the required public API to + set protocols and register application callbacks to negotiate the + protocol that will be tunneled over TLS. + @see ALPN section in the developer's guide for information. + */ +/* #define USE_ALPN */ + +/******************************************************************************/ +/** + Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the + sha1 hash of each CA file to the server for help in server selection. + This extra level of define is to help isolate the SHA1 requirement + */ +/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + A client side configuration that requires a server to provide an OCSP + response if the client uses the certitificate status request extension. + The "must staple" terminology is typically associated with certificates + at the X.509 layer but it is a good description of what is being required + of the server at the TLS level. + @pre USE_OCSP_RESPONSE must be enabled at the crypto level and the client + application must use the OCSPstapling session option at run time for this + setting to have any effect + */ +# ifdef USE_OCSP_RESPONSE +# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */ +# endif + +/******************************************************************************/ +/** + Rehandshaking support. + + Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the + protocol defined in RFC 5748 which fixed a critical exploit in + the standard TLS specification. + + @security Looking towards TLS 1.3, which removes re-handshaking, this + feature is disabled by default. + */ +/* #define USE_REHANDSHAKING */ + +/******************************************************************************//** + False Start support for Chrome and Firefox browsers. + @see https://tools.ietf.org/html/rfc7918 + + Some versions of Firefox browser and Chrome browser include support for + False Start. This flag will enable server side support on MatrixSSL + operating as server for client using false start feature. + + @note April 2012: Google has announced this feature will be removed in + version 20 of their browser due to industry compatibility issues. + However because there are other browsers using the feature, this feature + is often recommendable to enable for maximal browser compatibility. + */ +# define USE_SERVER_SIDE_FALSE_START_SUPPORT + +/******************************************************************************/ +/** + If SERVER you may define the number of sessions to cache and how + long a session will remain valid in the cache from first access. + Session caching enables very fast "session resumption handshakes". + + SSL_SESSION_TABLE_SIZE minimum value is 1 + SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0 + + @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0 + however, this will also immediately expire SESSION_TICKETS below. + */ +# ifdef USE_SERVER_SIDE_SSL +# define SSL_SESSION_TABLE_SIZE 32 +# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */ +# endif + +/******************************************************************************/ +/** + Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE + define applies to this method as well as the standard method. The + SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list. + */ +/* #define USE_STATELESS_SESSION_TICKETS */ +# define SSL_SESSION_TICKET_LIST_LEN 32 + +/******************************************************************************/ +/** + The initial buffer sizes for send and receive buffers in each ssl_t session. + Buffers are internally grown if more incoming or outgoing data storage is + needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the + buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced + to this size. Most standard SSL handshakes require on the order of 1024 B. + + SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE + */ +# ifndef USE_DTLS +# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */ +# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */ +# else +/******************************************************************************/ +/** + The Path Maximum Transmission Unit is the largest datagram that can be + sent or recieved. It is beyond the scope of DTLS to negotiate this value + so make sure both sides have agreed on this value. This is an enforced + limitation in MatrixDTLS so connections will not succeed if a peer has a + PTMU set larger than this value. + */ +# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */ +# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ +# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ + +/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ +# endif + +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + +# ifdef __cplusplus +} +# endif + +#endif /* _h_MATRIXCONFIG */ +/******************************************************************************/ diff --git a/configs/tls12-minimal/coreConfig.h b/configs/tls12-minimal/coreConfig.h new file mode 100644 index 0000000..5c39747 --- /dev/null +++ b/configs/tls12-minimal/coreConfig.h @@ -0,0 +1,109 @@ +/** + * @file coreConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for Matrix core module. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CORECONFIG +# define _h_PS_CORECONFIG + + +/******************************************************************************/ +/* Debug and tracing configuration */ +/******************************************************************************/ + +/** + Enable various levels of trace. + When these option is turned off, messages are silently + discarded and their text does not take space in the binary image. + */ +/* #define USE_CORE_TRACE */ +# ifndef NO_CORE_ERROR +# define USE_CORE_ERROR +# endif +# ifndef NO_CORE_ASSERT +# define USE_CORE_ASSERT +# endif + +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + +/******************************************************************************/ +/* Other Configurable features */ +/******************************************************************************/ + +/** + If enabled, calls to the psError set of APIs will perform a platform + abort on the exeutable to aid in debugging. + */ +# ifdef DEBUG +/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ +# endif + +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +# define NO_FILE_SYSTEM + +/** + Include the psCoreOsdepMutex family of APIs + + @note If intending to compile crypto-cl, then this flag should + always be set. +*/ +# ifndef NO_MULTITHREADING +/* #define USE_MULTITHREADING */ +# endif /* NO_MULTITHREADING */ + +/** + Include the psNetwork family of APIs. + + These APIs allow simple high-level socket api. + The API derive from BSD Sockets, and therefore it can only be used + on devices which have the prerequisitive APIs. + MatrixSSL itself can be used also be used without PS networking, but + many of example programs and MatrixSSLNet are based on PS networking. + */ +# ifndef NO_PS_NETWORKING +# define USE_PS_NETWORKING +# endif /* NO_PS_NETWORKING */ + +#endif /* _h_PS_CORECONFIG */ + +/******************************************************************************/ + diff --git a/configs/tls12-minimal/cryptoConfig.h b/configs/tls12-minimal/cryptoConfig.h new file mode 100644 index 0000000..876646c --- /dev/null +++ b/configs/tls12-minimal/cryptoConfig.h @@ -0,0 +1,309 @@ +/** + * @file cryptoConfig.h + * @version $Format:%h%d$ + * + * Configuration file for crypto features. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CRYPTOCONFIG +# define _h_PS_CRYPTOCONFIG + +/******************************************************************************/ +/* Configurable features */ +/******************************************************************************/ +/** + Define to enable psTrace*Crypto APIs for debugging the crypto module. + */ +/* #define USE_CRYPTO_TRACE */ + +# ifdef DEBUG +/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */ +# endif + +/******************************************************************************/ +/* + Use built-in cryptographic library delivered with MatrixSSL + */ +# define USE_NATIVE_RSA /* Default built-in software support */ + +/******************************************************************************/ +/** + Security related settings. + + @security MIN_*_BITS is the minimum supported key sizes in bits, weaker + keys will be rejected. + */ +# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */ + +# define MIN_RSA_BITS 1024 + +/* The configuration can define set minimum for RSA public exponent. + + For CL crypto, the default is 65537 (according to FIPS 186-4 standard). + It can be overridden on line below: + */ +/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */ + +# define MIN_DH_BITS 1024 + +# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */ + +/******************************************************************************/ +/** + Public-Key Algorithm Support. + */ +# define USE_RSA +# define USE_ECC +/* #define USE_DH */ +/**< @note Enable verification of DSA signatures in certificate validation. + Works only when using the CL/SL library. @pre USE_CERT_PARSE. */ +/* #define USE_DSA_VERIFY */ +# ifdef USE_DH +/**< @note Enable this if you intent to support Diffie-Hellman groups larger + than 4096. Usually such large groups are not used. */ +/* #define USE_LARGE_DH_GROUPS */ +# endif /* USE_DH */ +/**< @note Enable ECDHE with Curve25519. */ +/* #define USE_X25519 */ +/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures. + @pre USE_ECC, USE_SHA512. */ +/* #define USE_ED25519 */ + +/******************************************************************************/ +/** + Build the PKCS and ASN1 extra CL sublibraries. + These are needed by the CL_PKCS API. + */ + +/******************************************************************************/ + +/** + Define to enable the individual NIST Prime curves. + @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +# ifdef USE_ECC +/* #define USE_SECP192R1 *//**< @security FIPS allowed for sig ver only. */ +/* #define USE_SECP224R1 */ +# define USE_SECP256R1/**< @security NIST_SHALL */ +# define USE_SECP384R1/**< @security NIST_SHALL */ +# define USE_SECP521R1 +# endif + +/** + Define to enable the individual Brainpool curves. + @see https://tools.ietf.org/html/rfc5639 + @security WARNING: Public points on Brainpool curves are not validated + */ +# ifdef USE_ECC +/* #define USE_BRAIN224R1 */ +/* #define USE_BRAIN256R1 */ +/* #define USE_BRAIN384R1 */ +/* #define USE_BRAIN512R1 */ +# endif + +/******************************************************************************/ +/** + Symmetric and AEAD ciphers. + @security Deprecated ciphers must be enabled in cryptolib.h + */ +/* #define USE_AES *//* Enable/Disable AES */ +/* #define USE_AES_CBC */ +# define USE_AES_GCM + +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ +/* #define USE_CHACHA20_POLY1305_IETF */ + +/** @security 3DES is still relatively secure, however is deprecated for TLS */ +/* #define USE_3DES */ + +/******************************************************************************/ +/** + Legacy ciphers. + These ciphers have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher below need to disabled according to RFC 7465. +*/ +/* #define USE_ARC4 */ + +/******************************************************************************/ +/** + Digest algorithms. + + @note SHA256 and above are used with TLS 1.2, and also used for + certificate signatures on some certificates regardless of TLS version. + + @security MD5 is deprecated, but still required in combination with SHA-1 + for TLS handshakes before TLS 1.2, meaning that the strength is at least + that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable + MD5 only for this purpose. The only other usage of MD5 by TLS is for + certificate signatures and MD5 based cipher suites. Both of which are + disabled at compile time by default. + + @security SHA1 will be deprecated in the future, but is still required in + combination with MD5 for versions prior to TLS 1.2. In addition, SHA1 + certificates are still commonly used, so SHA1 support may be needed + to validate older certificates. It is possible to completely disable + SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting + only with newer certificates. + */ +/* #define USE_SHA224 *//**< @note Used only for cert signature */ +# define USE_SHA256/**< @note Required for TLS 1.2 and above */ +# define USE_HMAC_SHA256 +# define USE_SHA384/**< @pre USE_SHA512 */ +# define USE_HMAC_SHA384 +# define USE_SHA512 + +/** + @security SHA-1 based hashes are deprecated but enabled by default + @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_SHA1 */ +/* #define USE_HMAC_SHA1 */ + +/** + @security MD5 is considered insecure, but required by TLS < 1.2 + @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_MD5 */ +/* #define USE_MD5SHA1 *//* Required for < TLS 1.2 Handshake */ +/* #define USE_HMAC_MD5 */ + +/** + @security MD2 is considered insecure, but is sometimes used for + verification of legacy root certificate signatures. + @note MD2 signature verification also requires + ENABLE_MD5_SIGNED_CERTS and USE_MD5. + */ +/* #define USE_MD2 */ + +/* Please enable, unless using no HMAC algorithms. */ +# define USE_HMAC + +/** + HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869). + Needed in TLS 1.3 key derivation. +*/ +# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384) +# define USE_HKDF +# endif + +/******************************************************************************/ +/** + X.509 Certificates/PKI + */ +/* #define USE_BASE64_DECODE */ +# define USE_X509/**< Enable minimal X.509 support. */ +# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ +# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ +/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ +/**< Support extra distinguished name attributes not mentioned in RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ +/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ +/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ + +/** + @security SHA-1 based signatures are insecure, as SHA-1 can no longer + be considered collision resistant (https://shattered.it/static/shattered.pdf). + Enable if compatibility with old certificates is required. + */ +/* #define ENABLE_SHA1_SIGNED_CERTS */ + +/**< @security Allow parsing of locally trusted v1 root certs? */ +/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */ +/** + When parsing certificates, always also retain the unparsed DER data. + Enabling this has the same effect as setting the + CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call. + */ +/* #define ALWAYS_KEEP_CERT_DER */ +/** + Always attempt to match expectedName with the subject CN, even if + a supported, but non-matching subjectAltName was presented. + The default behaviour is to check the CN only when no supported SAN + was presented, in accordance with Section 6.4.4 of RFC 6125. + */ +/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */ +/* #define USE_CRL *//***< @pre USE_FULL_CERT_PARSE */ +# ifdef USE_CRL +/** + Allow CRL authentication to succeed even when signer CA's cert does not + have the keyUsage extension and thus no cRLSign bit. + Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension + and the cRLSign bit. + */ +/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */ +# endif +/** + Enable OCSP response and request handling. +*/ +/* #define USE_OCSP *//**< @pre USE_SHA1 */ +# ifdef USE_OCSP +# define USE_OCSP_RESPONSE +# elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) +/** + Enable parsing and writing of OCSP responses. This is enough + to support OCSP stapling. +*/ +/* #define USE_OCSP_RESPONSE *//**< @pre USE_SHA1 */ +#endif /* USE_OCSP */ + +/******************************************************************************/ +/** + Various PKCS standards support + */ +# define USE_PRIVATE_KEY_PARSING +/* #define USE_PKCS5 *//**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */ +/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */ +/* #define USE_PBKDF1 */ +/* #define USE_PKCS8 *//* Alternative private key storage format */ +/* #define USE_PKCS12 *//**< @pre USE_PKCS8 */ +/* #define USE_PKCS1_OAEP *//* OAEP padding algorithm */ +/* #define USE_PKCS1_PSS *//* PSS padding algorithm */ + +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +/* #define USE_BASE64_DECODE *//* Allow decoding Base64-encoded data. */ +/* #define USE_PEM_DECODE *//* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + +#endif /* _h_PS_CRYPTOCONFIG */ + +/******************************************************************************/ diff --git a/configs/tls12-minimal/matrixsslConfig.h b/configs/tls12-minimal/matrixsslConfig.h new file mode 100644 index 0000000..e11b2c8 --- /dev/null +++ b/configs/tls12-minimal/matrixsslConfig.h @@ -0,0 +1,447 @@ +/** + * @file matrixsslConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for building the MatrixSSL library. + * This configuration is intended to be used in FIPS Mode of operation. + * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and + * to enable the most commonly used cipher suites. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSLCONFIG +# define _h_MATRIXSSLCONFIG + +# ifdef __cplusplus +extern "C" { +# endif + +/** + NIST SP 800-52 Rev 1 Conformance. + Guidelines for the Selection, Configuration, and Use of Transport Layer + Security (TLS) Implementations + The key words "shall", "shall not", "should", "should not" and "may" + are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as + "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility + is not relevant. + @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf + */ + +/******************************************************************************/ +/** + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. + */ +/* #define USE_SSL_HANDSHAKE_MSG_TRACE */ + +/** + Informational trace that could help pinpoint problems with TLS/DTLS + connections. + */ +/* #define USE_SSL_INFORMATIONAL_TRACE */ +/* #define USE_DTLS_DEBUG_TRACE */ + +/******************************************************************************/ +/** + Recommended cipher suites. + Define the following to enable various cipher suites + At least one of these must be defined. If multiple are defined, + the handshake negotiation will determine which is best for the connection. + @note Ephemeral ciphersuites offer perfect forward security (PFS) + at the cost of a slower TLS handshake. + */ + +/** TLS 1.3 ciphers */ +/* #define USE_TLS_AES_128_GCM_SHA256 */ +/* #define USE_TLS_AES_256_GCM_SHA384 */ +/* #define USE_TLS_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +# define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */ +# define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA256 *//**< @security NIST_MAY */ +# define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + These cipher suites are secure, but not widely deployed. + */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */ + +/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */ +/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */ + +/** Pre-Shared Key Ciphers. + NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary + See NIST SP 800-52 Rev 1 Appendix C */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA384 *//**< @security NIST_SHOULD_NOT */ + +/** Non-Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_MAY */ + +/** Non-Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */ + +/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52 + Rev 1 are not supported by the MatrixSSL / MatrixDTLS. + ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (NIST SP 800-52 Rev 1 "should") + is rarely used cipher suite and is not supported. + Also (NIST SP 800-52 Rev 1 "may") TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be + enabled as they are not supported. */ + +/******************************************************************************/ +/** + Legacy cipher suites. + These cipher suites have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher suites below need to disabled according to RFC 7465. +*/ +/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */ + +/******************************************************************************/ +/** + Ephemeral key cache support. + If not using cache, new key exchange keys are created for each TLS session. + If using cache, keys are generated initially, and re-used in each + subsequent TLS connection within a given time frame and usage count. + @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE + + @security Do not cache Ephemeral ECC keys as it is against some standards, + including NIST SP 800-56A, when in FIPS 140-2 mode of operation. + */ +# define NO_ECC_EPHEMERAL_CACHE/**< @security NIST_SHALL */ + +/******************************************************************************/ +/** + Configure Support for TLS protocol versions. + Define one of: + USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3) + USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3) + USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3) + @note There is no option for enabling SSL3.0 at this level + */ +/* #define USE_TLS_1_1_AND_ABOVE *//**< @security default 1_1_AND_ABOVE */ +# define USE_TLS_1_2_AND_ABOVE/**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */ +/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */ + +/** Enable support for session resumption in TLS 1.3. */ +/* #define USE_TLS_1_3_RESUMPTION */ + +/** TLS 1.3 code has not yet been footprint-optimized. For this reason, + it is possible to separately leave all TLS 1.3 code out of the build + by enabling this. */ +# define DISABLE_TLS_1_3 + +/******************************************************************************/ +/** + Datagram TLS support. + Enables DTLS in addition to TLS. + @pre TLS_1_1 + */ +/* #define USE_DTLS */ + +/******************************************************************************/ +/** + Compile time support for server or client side SSL + */ +# define USE_CLIENT_SIDE_SSL +# define USE_SERVER_SIDE_SSL + +/******************************************************************************/ +/** + Allow the server to parse SSL 2.0 ClientHello messages even when the + server does not actually support SSL 2.0. As per RFC 5246, E.2: + + "... even TLS servers that do not support SSL 2.0 MAY accept version + 2.0 CLIENT-HELLO messages." + + This option is for compatibility with clients that support + SSL 2.0 but are ready to negotiate a higher version such as TLS 1.0. + Note that enabling this option will only allow parsing of the SSL 2.0 + ClientHellos; it will not enable support for the SSL 2.0 protocol. + Only 32-byte challenges in the SSL 2.0 ClientHello are supported. +*/ +# ifdef USE_SERVER_SIDE_SSL +/* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ +# endif + +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + +/******************************************************************************/ +/** + Client certificate authentication + */ +# define USE_CLIENT_AUTH + +# ifdef USE_CLIENT_AUTH +/** + Enable the handshake_messages signature in the CertificateVerify + protocol message to be signed using an external module. + */ +/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */ +# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING +/** + Compile an example external module that allows the + USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example + client program and sslTest. + */ +/* #define USE_EXT_EXAMPLE_MODULE */ +# endif + +/** + Enable loading of a new client certificate and private key + in response to a CertificateRequest message from a server. This feature + allows the client program to e.g. select a client certificate + whose issuer is included in the server's list of trusted CAs + that was received in the CertificateRequest message. +*/ +/* #define USE_EXT_CLIENT_CERT_KEY_LOADING */ +# endif /* USE_CLIENT_AUTH */ + +/** + Enable if the server should send an empty CertificateRequest message if + no CA files have been loaded + */ +/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */ + +/** + Enabling this define will allow the server to "downgrade" a client auth + handshake to a standard handshake if the client replies to a + CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback + will be called with a NULL cert in this case and the user can determine if + the handshake should continue in a non-client auth state. + */ +/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ + +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + +/******************************************************************************/ +/** + Enable the Application Layer Protocol Negotiation extension. + Servers and Clients will still have to use the required public API to + set protocols and register application callbacks to negotiate the + protocol that will be tunneled over TLS. + @see ALPN section in the developer's guide for information. + */ +/* #define USE_ALPN */ + +/******************************************************************************/ +/** + Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the + sha1 hash of each CA file to the server for help in server selection. + This extra level of define is to help isolate the SHA1 requirement + */ +/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + A client side configuration that requires a server to provide an OCSP + response if the client uses the certitificate status request extension. + The "must staple" terminology is typically associated with certificates + at the X.509 layer but it is a good description of what is being required + of the server at the TLS level. + @pre USE_OCSP_RESPONSE must be enabled at the crypto level and the client + application must use the OCSPstapling session option at run time for this + setting to have any effect + */ +# ifdef USE_OCSP_RESPONSE +# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */ +# endif + +/******************************************************************************/ +/** + Rehandshaking support. + + Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the + protocol defined in RFC 5748 which fixed a critical exploit in + the standard TLS specification. + + @security Looking towards TLS 1.3, which removes re-handshaking, this + feature is disabled by default. + */ +/* #define USE_REHANDSHAKING */ + +/******************************************************************************//** + False Start support for Chrome and Firefox browsers. + @see https://tools.ietf.org/html/rfc7918 + + Some versions of Firefox browser and Chrome browser include support for + False Start. This flag will enable server side support on MatrixSSL + operating as server for client using false start feature. + + @note April 2012: Google has announced this feature will be removed in + version 20 of their browser due to industry compatibility issues. + However because there are other browsers using the feature, this feature + is often recommendable to enable for maximal browser compatibility. + */ +# define USE_SERVER_SIDE_FALSE_START_SUPPORT + +/******************************************************************************/ +/** + If SERVER you may define the number of sessions to cache and how + long a session will remain valid in the cache from first access. + Session caching enables very fast "session resumption handshakes". + + SSL_SESSION_TABLE_SIZE minimum value is 1 + SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0 + + @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0 + however, this will also immediately expire SESSION_TICKETS below. + */ +# ifdef USE_SERVER_SIDE_SSL +# define SSL_SESSION_TABLE_SIZE 32 +# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */ +# endif + +/******************************************************************************/ +/** + Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE + define applies to this method as well as the standard method. The + SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list. + */ +/* #define USE_STATELESS_SESSION_TICKETS */ +# define SSL_SESSION_TICKET_LIST_LEN 32 + +/******************************************************************************/ +/** + The initial buffer sizes for send and receive buffers in each ssl_t session. + Buffers are internally grown if more incoming or outgoing data storage is + needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the + buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced + to this size. Most standard SSL handshakes require on the order of 1024 B. + + SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE + */ +# ifndef USE_DTLS +# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */ +# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */ +# else +/******************************************************************************/ +/** + The Path Maximum Transmission Unit is the largest datagram that can be + sent or recieved. It is beyond the scope of DTLS to negotiate this value + so make sure both sides have agreed on this value. This is an enforced + limitation in MatrixDTLS so connections will not succeed if a peer has a + PTMU set larger than this value. + */ +# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */ +# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ +# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ + +/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ +# endif + +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + +# ifdef __cplusplus +} +# endif + +#endif /* _h_MATRIXCONFIG */ +/******************************************************************************/ diff --git a/configs/tls13-minimal-client-ecc/coreConfig.h b/configs/tls13-minimal-client-ecc/coreConfig.h new file mode 100644 index 0000000..5c39747 --- /dev/null +++ b/configs/tls13-minimal-client-ecc/coreConfig.h @@ -0,0 +1,109 @@ +/** + * @file coreConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for Matrix core module. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CORECONFIG +# define _h_PS_CORECONFIG + + +/******************************************************************************/ +/* Debug and tracing configuration */ +/******************************************************************************/ + +/** + Enable various levels of trace. + When these option is turned off, messages are silently + discarded and their text does not take space in the binary image. + */ +/* #define USE_CORE_TRACE */ +# ifndef NO_CORE_ERROR +# define USE_CORE_ERROR +# endif +# ifndef NO_CORE_ASSERT +# define USE_CORE_ASSERT +# endif + +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + +/******************************************************************************/ +/* Other Configurable features */ +/******************************************************************************/ + +/** + If enabled, calls to the psError set of APIs will perform a platform + abort on the exeutable to aid in debugging. + */ +# ifdef DEBUG +/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ +# endif + +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +# define NO_FILE_SYSTEM + +/** + Include the psCoreOsdepMutex family of APIs + + @note If intending to compile crypto-cl, then this flag should + always be set. +*/ +# ifndef NO_MULTITHREADING +/* #define USE_MULTITHREADING */ +# endif /* NO_MULTITHREADING */ + +/** + Include the psNetwork family of APIs. + + These APIs allow simple high-level socket api. + The API derive from BSD Sockets, and therefore it can only be used + on devices which have the prerequisitive APIs. + MatrixSSL itself can be used also be used without PS networking, but + many of example programs and MatrixSSLNet are based on PS networking. + */ +# ifndef NO_PS_NETWORKING +# define USE_PS_NETWORKING +# endif /* NO_PS_NETWORKING */ + +#endif /* _h_PS_CORECONFIG */ + +/******************************************************************************/ + diff --git a/configs/tls13-minimal-client-ecc/cryptoConfig.h b/configs/tls13-minimal-client-ecc/cryptoConfig.h new file mode 100644 index 0000000..5d1dcf1 --- /dev/null +++ b/configs/tls13-minimal-client-ecc/cryptoConfig.h @@ -0,0 +1,309 @@ +/** + * @file cryptoConfig.h + * @version $Format:%h%d$ + * + * Configuration file for crypto features. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CRYPTOCONFIG +# define _h_PS_CRYPTOCONFIG + +/******************************************************************************/ +/* Configurable features */ +/******************************************************************************/ +/** + Define to enable psTrace*Crypto APIs for debugging the crypto module. + */ +/* #define USE_CRYPTO_TRACE */ + +# ifdef DEBUG +/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */ +# endif + +/******************************************************************************/ +/* + Use built-in cryptographic library delivered with MatrixSSL + */ +# define USE_NATIVE_RSA /* Default built-in software support */ + +/******************************************************************************/ +/** + Security related settings. + + @security MIN_*_BITS is the minimum supported key sizes in bits, weaker + keys will be rejected. + */ +# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */ + +# define MIN_RSA_BITS 1024 + +/* The configuration can define set minimum for RSA public exponent. + + For CL crypto, the default is 65537 (according to FIPS 186-4 standard). + It can be overridden on line below: + */ +/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */ + +# define MIN_DH_BITS 1024 + +# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */ + +/******************************************************************************/ +/** + Public-Key Algorithm Support. + */ +/* #define USE_RSA */ +# define USE_ECC +/* #define USE_DH */ +/**< @note Enable verification of DSA signatures in certificate validation. + Works only when using the CL/SL library. @pre USE_CERT_PARSE. */ +/* #define USE_DSA_VERIFY */ +# ifdef USE_DH +/**< @note Enable this if you intent to support Diffie-Hellman groups larger + than 4096. Usually such large groups are not used. */ +/* #define USE_LARGE_DH_GROUPS */ +# endif /* USE_DH */ +/**< @note Enable ECDHE with Curve25519. */ +/* #define USE_X25519 */ +/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures. + @pre USE_ECC, USE_SHA512. */ +/* #define USE_ED25519 */ + +/******************************************************************************/ +/** + Build the PKCS and ASN1 extra CL sublibraries. + These are needed by the CL_PKCS API. + */ + +/******************************************************************************/ + +/** + Define to enable the individual NIST Prime curves. + @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +# ifdef USE_ECC +/* #define USE_SECP192R1 *//**< @security FIPS allowed for sig ver only. */ +/* #define USE_SECP224R1 */ +# define USE_SECP256R1/**< @security NIST_SHALL */ +# define USE_SECP384R1/**< @security NIST_SHALL */ +# define USE_SECP521R1 +# endif + +/** + Define to enable the individual Brainpool curves. + @see https://tools.ietf.org/html/rfc5639 + @security WARNING: Public points on Brainpool curves are not validated + */ +# ifdef USE_ECC +/* #define USE_BRAIN224R1 */ +/* #define USE_BRAIN256R1 */ +/* #define USE_BRAIN384R1 */ +/* #define USE_BRAIN512R1 */ +# endif + +/******************************************************************************/ +/** + Symmetric and AEAD ciphers. + @security Deprecated ciphers must be enabled in cryptolib.h + */ +/* #define USE_AES *//* Enable/Disable AES */ +# define USE_AES_CBC +# define USE_AES_GCM + +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ +/* #define USE_CHACHA20_POLY1305_IETF */ + +/** @security 3DES is still relatively secure, however is deprecated for TLS */ +/* #define USE_3DES */ + +/******************************************************************************/ +/** + Legacy ciphers. + These ciphers have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher below need to disabled according to RFC 7465. +*/ +/* #define USE_ARC4 */ + +/******************************************************************************/ +/** + Digest algorithms. + + @note SHA256 and above are used with TLS 1.2, and also used for + certificate signatures on some certificates regardless of TLS version. + + @security MD5 is deprecated, but still required in combination with SHA-1 + for TLS handshakes before TLS 1.2, meaning that the strength is at least + that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable + MD5 only for this purpose. The only other usage of MD5 by TLS is for + certificate signatures and MD5 based cipher suites. Both of which are + disabled at compile time by default. + + @security SHA1 will be deprecated in the future, but is still required in + combination with MD5 for versions prior to TLS 1.2. In addition, SHA1 + certificates are still commonly used, so SHA1 support may be needed + to validate older certificates. It is possible to completely disable + SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting + only with newer certificates. + */ +/* #define USE_SHA224 *//**< @note Used only for cert signature */ +# define USE_SHA256/**< @note Required for TLS 1.2 and above */ +# define USE_HMAC_SHA256 +# define USE_SHA384/**< @pre USE_SHA512 */ +# define USE_HMAC_SHA384 +# define USE_SHA512 + +/** + @security SHA-1 based hashes are deprecated but enabled by default + @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_SHA1 */ +/* #define USE_HMAC_SHA1 */ + +/** + @security MD5 is considered insecure, but required by TLS < 1.2 + @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_MD5 */ +/* #define USE_MD5SHA1 *//* Required for < TLS 1.2 Handshake */ +/* #define USE_HMAC_MD5 */ + +/** + @security MD2 is considered insecure, but is sometimes used for + verification of legacy root certificate signatures. + @note MD2 signature verification also requires + ENABLE_MD5_SIGNED_CERTS and USE_MD5. + */ +/* #define USE_MD2 */ + +/* Please enable, unless using no HMAC algorithms. */ +# define USE_HMAC + +/** + HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869). + Needed in TLS 1.3 key derivation. +*/ +# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384) +# define USE_HKDF +# endif + +/******************************************************************************/ +/** + X.509 Certificates/PKI + */ +/* #define USE_BASE64_DECODE */ +# define USE_X509/**< Enable minimal X.509 support. */ +# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ +# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ +/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ +/**< Support extra distinguished name attributes not mentioned in RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ +/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ +/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ + +/** + @security SHA-1 based signatures are insecure, as SHA-1 can no longer + be considered collision resistant (https://shattered.it/static/shattered.pdf). + Enable if compatibility with old certificates is required. + */ +/* #define ENABLE_SHA1_SIGNED_CERTS */ + +/**< @security Allow parsing of locally trusted v1 root certs? */ +/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */ +/** + When parsing certificates, always also retain the unparsed DER data. + Enabling this has the same effect as setting the + CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call. + */ +/* #define ALWAYS_KEEP_CERT_DER */ +/** + Always attempt to match expectedName with the subject CN, even if + a supported, but non-matching subjectAltName was presented. + The default behaviour is to check the CN only when no supported SAN + was presented, in accordance with Section 6.4.4 of RFC 6125. + */ +/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */ +/* #define USE_CRL *//***< @pre USE_FULL_CERT_PARSE */ +# ifdef USE_CRL +/** + Allow CRL authentication to succeed even when signer CA's cert does not + have the keyUsage extension and thus no cRLSign bit. + Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension + and the cRLSign bit. + */ +/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */ +# endif +/** + Enable OCSP response and request handling. +*/ +/* #define USE_OCSP *//**< @pre USE_SHA1 */ +# ifdef USE_OCSP +# define USE_OCSP_RESPONSE +# elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) +/** + Enable parsing and writing of OCSP responses. This is enough + to support OCSP stapling. +*/ +/* #define USE_OCSP_RESPONSE *//**< @pre USE_SHA1 */ +#endif /* USE_OCSP */ + +/******************************************************************************/ +/** + Various PKCS standards support + */ +# define USE_PRIVATE_KEY_PARSING +/* #define USE_PKCS5 *//**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */ +/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */ +/* #define USE_PBKDF1 */ +/* #define USE_PKCS8 *//* Alternative private key storage format */ +/* #define USE_PKCS12 *//**< @pre USE_PKCS8 */ +/* #define USE_PKCS1_OAEP *//* OAEP padding algorithm */ +# define USE_PKCS1_PSS/* PSS padding algorithm */ + +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +/* #define USE_BASE64_DECODE *//* Allow decoding Base64-encoded data. */ +/* #define USE_PEM_DECODE *//* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + +#endif /* _h_PS_CRYPTOCONFIG */ + +/******************************************************************************/ diff --git a/configs/tls13-minimal-client-ecc/matrixsslConfig.h b/configs/tls13-minimal-client-ecc/matrixsslConfig.h new file mode 100644 index 0000000..a519edf --- /dev/null +++ b/configs/tls13-minimal-client-ecc/matrixsslConfig.h @@ -0,0 +1,447 @@ +/** + * @file matrixsslConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for building the MatrixSSL library. + * This configuration is intended to be used in FIPS Mode of operation. + * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and + * to enable the most commonly used cipher suites. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSLCONFIG +# define _h_MATRIXSSLCONFIG + +# ifdef __cplusplus +extern "C" { +# endif + +/** + NIST SP 800-52 Rev 1 Conformance. + Guidelines for the Selection, Configuration, and Use of Transport Layer + Security (TLS) Implementations + The key words "shall", "shall not", "should", "should not" and "may" + are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as + "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility + is not relevant. + @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf + */ + +/******************************************************************************/ +/** + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. + */ +/* #define USE_SSL_HANDSHAKE_MSG_TRACE */ + +/** + Informational trace that could help pinpoint problems with TLS/DTLS + connections. + */ +/* #define USE_SSL_INFORMATIONAL_TRACE */ +/* #define USE_DTLS_DEBUG_TRACE */ + +/******************************************************************************/ +/** + Recommended cipher suites. + Define the following to enable various cipher suites + At least one of these must be defined. If multiple are defined, + the handshake negotiation will determine which is best for the connection. + @note Ephemeral ciphersuites offer perfect forward security (PFS) + at the cost of a slower TLS handshake. + */ + +/** TLS 1.3 ciphers */ +# define USE_TLS_AES_128_GCM_SHA256 +/* #define USE_TLS_AES_256_GCM_SHA384 */ +/* #define USE_TLS_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + These cipher suites are secure, but not widely deployed. + */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */ + +/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */ +/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */ + +/** Pre-Shared Key Ciphers. + NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary + See NIST SP 800-52 Rev 1 Appendix C */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA384 *//**< @security NIST_SHOULD_NOT */ + +/** Non-Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_MAY */ + +/** Non-Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */ + +/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52 + Rev 1 are not supported by the MatrixSSL / MatrixDTLS. + ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (NIST SP 800-52 Rev 1 "should") + is rarely used cipher suite and is not supported. + Also (NIST SP 800-52 Rev 1 "may") TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be + enabled as they are not supported. */ + +/******************************************************************************/ +/** + Legacy cipher suites. + These cipher suites have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher suites below need to disabled according to RFC 7465. +*/ +/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */ + +/******************************************************************************/ +/** + Ephemeral key cache support. + If not using cache, new key exchange keys are created for each TLS session. + If using cache, keys are generated initially, and re-used in each + subsequent TLS connection within a given time frame and usage count. + @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE + + @security Do not cache Ephemeral ECC keys as it is against some standards, + including NIST SP 800-56A, when in FIPS 140-2 mode of operation. + */ +# define NO_ECC_EPHEMERAL_CACHE/**< @security NIST_SHALL */ + +/******************************************************************************/ +/** + Configure Support for TLS protocol versions. + Define one of: + USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3) + USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3) + USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3) + @note There is no option for enabling SSL3.0 at this level + */ +/* #define USE_TLS_1_1_AND_ABOVE *//**< @security default 1_1_AND_ABOVE */ +# define USE_TLS_1_2_AND_ABOVE/**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */ +/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */ + +/** Enable support for session resumption in TLS 1.3. */ +# define USE_TLS_1_3_RESUMPTION + +/** TLS 1.3 code has not yet been footprint-optimized. For this reason, + it is possible to separately leave all TLS 1.3 code out of the build + by enabling this. */ +/* #define DISABLE_TLS_1_3 */ + +/******************************************************************************/ +/** + Datagram TLS support. + Enables DTLS in addition to TLS. + @pre TLS_1_1 + */ +/* #define USE_DTLS */ + +/******************************************************************************/ +/** + Compile time support for server or client side SSL + */ +# define USE_CLIENT_SIDE_SSL +/* #define USE_SERVER_SIDE_SSL */ + +/******************************************************************************/ +/** + Allow the server to parse SSL 2.0 ClientHello messages even when the + server does not actually support SSL 2.0. As per RFC 5246, E.2: + + "... even TLS servers that do not support SSL 2.0 MAY accept version + 2.0 CLIENT-HELLO messages." + + This option is for compatibility with clients that support + SSL 2.0 but are ready to negotiate a higher version such as TLS 1.0. + Note that enabling this option will only allow parsing of the SSL 2.0 + ClientHellos; it will not enable support for the SSL 2.0 protocol. + Only 32-byte challenges in the SSL 2.0 ClientHello are supported. +*/ +# ifdef USE_SERVER_SIDE_SSL +/* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ +# endif + +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + +/******************************************************************************/ +/** + Client certificate authentication + */ +# define USE_CLIENT_AUTH + +# ifdef USE_CLIENT_AUTH +/** + Enable the handshake_messages signature in the CertificateVerify + protocol message to be signed using an external module. + */ +/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */ +# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING +/** + Compile an example external module that allows the + USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example + client program and sslTest. + */ +/* #define USE_EXT_EXAMPLE_MODULE */ +# endif + +/** + Enable loading of a new client certificate and private key + in response to a CertificateRequest message from a server. This feature + allows the client program to e.g. select a client certificate + whose issuer is included in the server's list of trusted CAs + that was received in the CertificateRequest message. +*/ +/* #define USE_EXT_CLIENT_CERT_KEY_LOADING */ +# endif /* USE_CLIENT_AUTH */ + +/** + Enable if the server should send an empty CertificateRequest message if + no CA files have been loaded + */ +/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */ + +/** + Enabling this define will allow the server to "downgrade" a client auth + handshake to a standard handshake if the client replies to a + CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback + will be called with a NULL cert in this case and the user can determine if + the handshake should continue in a non-client auth state. + */ +/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ + +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + +/******************************************************************************/ +/** + Enable the Application Layer Protocol Negotiation extension. + Servers and Clients will still have to use the required public API to + set protocols and register application callbacks to negotiate the + protocol that will be tunneled over TLS. + @see ALPN section in the developer's guide for information. + */ +/* #define USE_ALPN */ + +/******************************************************************************/ +/** + Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the + sha1 hash of each CA file to the server for help in server selection. + This extra level of define is to help isolate the SHA1 requirement + */ +/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + A client side configuration that requires a server to provide an OCSP + response if the client uses the certitificate status request extension. + The "must staple" terminology is typically associated with certificates + at the X.509 layer but it is a good description of what is being required + of the server at the TLS level. + @pre USE_OCSP_RESPONSE must be enabled at the crypto level and the client + application must use the OCSPstapling session option at run time for this + setting to have any effect + */ +# ifdef USE_OCSP_RESPONSE +# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */ +# endif + +/******************************************************************************/ +/** + Rehandshaking support. + + Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the + protocol defined in RFC 5748 which fixed a critical exploit in + the standard TLS specification. + + @security Looking towards TLS 1.3, which removes re-handshaking, this + feature is disabled by default. + */ +/* #define USE_REHANDSHAKING */ + +/******************************************************************************//** + False Start support for Chrome and Firefox browsers. + @see https://tools.ietf.org/html/rfc7918 + + Some versions of Firefox browser and Chrome browser include support for + False Start. This flag will enable server side support on MatrixSSL + operating as server for client using false start feature. + + @note April 2012: Google has announced this feature will be removed in + version 20 of their browser due to industry compatibility issues. + However because there are other browsers using the feature, this feature + is often recommendable to enable for maximal browser compatibility. + */ +# define USE_SERVER_SIDE_FALSE_START_SUPPORT + +/******************************************************************************/ +/** + If SERVER you may define the number of sessions to cache and how + long a session will remain valid in the cache from first access. + Session caching enables very fast "session resumption handshakes". + + SSL_SESSION_TABLE_SIZE minimum value is 1 + SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0 + + @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0 + however, this will also immediately expire SESSION_TICKETS below. + */ +# ifdef USE_SERVER_SIDE_SSL +# define SSL_SESSION_TABLE_SIZE 32 +# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */ +# endif + +/******************************************************************************/ +/** + Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE + define applies to this method as well as the standard method. The + SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list. + */ +# define USE_STATELESS_SESSION_TICKETS +# define SSL_SESSION_TICKET_LIST_LEN 32 + +/******************************************************************************/ +/** + The initial buffer sizes for send and receive buffers in each ssl_t session. + Buffers are internally grown if more incoming or outgoing data storage is + needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the + buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced + to this size. Most standard SSL handshakes require on the order of 1024 B. + + SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE + */ +# ifndef USE_DTLS +# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */ +# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */ +# else +/******************************************************************************/ +/** + The Path Maximum Transmission Unit is the largest datagram that can be + sent or recieved. It is beyond the scope of DTLS to negotiate this value + so make sure both sides have agreed on this value. This is an enforced + limitation in MatrixDTLS so connections will not succeed if a peer has a + PTMU set larger than this value. + */ +# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */ +# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ +# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ + +/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ +# endif + +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + +# ifdef __cplusplus +} +# endif + +#endif /* _h_MATRIXCONFIG */ +/******************************************************************************/ diff --git a/configs/tls13-minimal/coreConfig.h b/configs/tls13-minimal/coreConfig.h new file mode 100644 index 0000000..5c39747 --- /dev/null +++ b/configs/tls13-minimal/coreConfig.h @@ -0,0 +1,109 @@ +/** + * @file coreConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for Matrix core module. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CORECONFIG +# define _h_PS_CORECONFIG + + +/******************************************************************************/ +/* Debug and tracing configuration */ +/******************************************************************************/ + +/** + Enable various levels of trace. + When these option is turned off, messages are silently + discarded and their text does not take space in the binary image. + */ +/* #define USE_CORE_TRACE */ +# ifndef NO_CORE_ERROR +# define USE_CORE_ERROR +# endif +# ifndef NO_CORE_ASSERT +# define USE_CORE_ASSERT +# endif + +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + +/******************************************************************************/ +/* Other Configurable features */ +/******************************************************************************/ + +/** + If enabled, calls to the psError set of APIs will perform a platform + abort on the exeutable to aid in debugging. + */ +# ifdef DEBUG +/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ +# endif + +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +# define NO_FILE_SYSTEM + +/** + Include the psCoreOsdepMutex family of APIs + + @note If intending to compile crypto-cl, then this flag should + always be set. +*/ +# ifndef NO_MULTITHREADING +/* #define USE_MULTITHREADING */ +# endif /* NO_MULTITHREADING */ + +/** + Include the psNetwork family of APIs. + + These APIs allow simple high-level socket api. + The API derive from BSD Sockets, and therefore it can only be used + on devices which have the prerequisitive APIs. + MatrixSSL itself can be used also be used without PS networking, but + many of example programs and MatrixSSLNet are based on PS networking. + */ +# ifndef NO_PS_NETWORKING +# define USE_PS_NETWORKING +# endif /* NO_PS_NETWORKING */ + +#endif /* _h_PS_CORECONFIG */ + +/******************************************************************************/ + diff --git a/configs/tls13-minimal/cryptoConfig.h b/configs/tls13-minimal/cryptoConfig.h new file mode 100644 index 0000000..f643a56 --- /dev/null +++ b/configs/tls13-minimal/cryptoConfig.h @@ -0,0 +1,309 @@ +/** + * @file cryptoConfig.h + * @version $Format:%h%d$ + * + * Configuration file for crypto features. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_PS_CRYPTOCONFIG +# define _h_PS_CRYPTOCONFIG + +/******************************************************************************/ +/* Configurable features */ +/******************************************************************************/ +/** + Define to enable psTrace*Crypto APIs for debugging the crypto module. + */ +/* #define USE_CRYPTO_TRACE */ + +# ifdef DEBUG +/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */ +# endif + +/******************************************************************************/ +/* + Use built-in cryptographic library delivered with MatrixSSL + */ +# define USE_NATIVE_RSA /* Default built-in software support */ + +/******************************************************************************/ +/** + Security related settings. + + @security MIN_*_BITS is the minimum supported key sizes in bits, weaker + keys will be rejected. + */ +# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */ + +# define MIN_RSA_BITS 1024 + +/* The configuration can define set minimum for RSA public exponent. + + For CL crypto, the default is 65537 (according to FIPS 186-4 standard). + It can be overridden on line below: + */ +/* #define MIN_RSA_PUBLIC_EXPONENT 65537 *//* Valid values 3, 5, 17, 65537. */ + +# define MIN_DH_BITS 1024 + +# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */ + +/******************************************************************************/ +/** + Public-Key Algorithm Support. + */ +# define USE_RSA +# define USE_ECC +/* #define USE_DH */ +/**< @note Enable verification of DSA signatures in certificate validation. + Works only when using the CL/SL library. @pre USE_CERT_PARSE. */ +/* #define USE_DSA_VERIFY */ +# ifdef USE_DH +/**< @note Enable this if you intent to support Diffie-Hellman groups larger + than 4096. Usually such large groups are not used. */ +/* #define USE_LARGE_DH_GROUPS */ +# endif /* USE_DH */ +/**< @note Enable ECDHE with Curve25519. */ +/* #define USE_X25519 */ +/**< @note Enable Pure EdDSA Curve25519 (Ed25519) signatures. + @pre USE_ECC, USE_SHA512. */ +/* #define USE_ED25519 */ + +/******************************************************************************/ +/** + Build the PKCS and ASN1 extra CL sublibraries. + These are needed by the CL_PKCS API. + */ + +/******************************************************************************/ + +/** + Define to enable the individual NIST Prime curves. + @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +# ifdef USE_ECC +/* #define USE_SECP192R1 *//**< @security FIPS allowed for sig ver only. */ +/* #define USE_SECP224R1 */ +# define USE_SECP256R1/**< @security NIST_SHALL */ +# define USE_SECP384R1/**< @security NIST_SHALL */ +# define USE_SECP521R1 +# endif + +/** + Define to enable the individual Brainpool curves. + @see https://tools.ietf.org/html/rfc5639 + @security WARNING: Public points on Brainpool curves are not validated + */ +# ifdef USE_ECC +/* #define USE_BRAIN224R1 */ +/* #define USE_BRAIN256R1 */ +/* #define USE_BRAIN384R1 */ +/* #define USE_BRAIN512R1 */ +# endif + +/******************************************************************************/ +/** + Symmetric and AEAD ciphers. + @security Deprecated ciphers must be enabled in cryptolib.h + */ +/* #define USE_AES *//* Enable/Disable AES */ +# define USE_AES_CBC +# define USE_AES_GCM + +/** If you want new ciphersuites specified in RFC 7539 enable this. + Currently CHACHA20-based cipher suites are only supported by the newest + TLS clients and servers. These cipher suites are not allowed in FIPS + mode of operation. +*/ +/* #define USE_CHACHA20_POLY1305_IETF */ + +/** @security 3DES is still relatively secure, however is deprecated for TLS */ +/* #define USE_3DES */ + +/******************************************************************************/ +/** + Legacy ciphers. + These ciphers have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher below need to disabled according to RFC 7465. +*/ +/* #define USE_ARC4 */ + +/******************************************************************************/ +/** + Digest algorithms. + + @note SHA256 and above are used with TLS 1.2, and also used for + certificate signatures on some certificates regardless of TLS version. + + @security MD5 is deprecated, but still required in combination with SHA-1 + for TLS handshakes before TLS 1.2, meaning that the strength is at least + that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable + MD5 only for this purpose. The only other usage of MD5 by TLS is for + certificate signatures and MD5 based cipher suites. Both of which are + disabled at compile time by default. + + @security SHA1 will be deprecated in the future, but is still required in + combination with MD5 for versions prior to TLS 1.2. In addition, SHA1 + certificates are still commonly used, so SHA1 support may be needed + to validate older certificates. It is possible to completely disable + SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting + only with newer certificates. + */ +/* #define USE_SHA224 *//**< @note Used only for cert signature */ +# define USE_SHA256/**< @note Required for TLS 1.2 and above */ +# define USE_HMAC_SHA256 +# define USE_SHA384/**< @pre USE_SHA512 */ +# define USE_HMAC_SHA384 +# define USE_SHA512 + +/** + @security SHA-1 based hashes are deprecated but enabled by default + @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_SHA1 */ +/* #define USE_HMAC_SHA1 */ + +/** + @security MD5 is considered insecure, but required by TLS < 1.2 + @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below. + */ +/* #define USE_MD5 */ +/* #define USE_MD5SHA1 *//* Required for < TLS 1.2 Handshake */ +/* #define USE_HMAC_MD5 */ + +/** + @security MD2 is considered insecure, but is sometimes used for + verification of legacy root certificate signatures. + @note MD2 signature verification also requires + ENABLE_MD5_SIGNED_CERTS and USE_MD5. + */ +/* #define USE_MD2 */ + +/* Please enable, unless using no HMAC algorithms. */ +# define USE_HMAC + +/** + HMAC-based Extract-and-Expand Key Derivation Function (HKDF) (RFC 5869). + Needed in TLS 1.3 key derivation. +*/ +# if defined(USE_HMAC_SHA256) || defined(USE_HMAC_SHA384) +# define USE_HKDF +# endif + +/******************************************************************************/ +/** + X.509 Certificates/PKI + */ +/* #define USE_BASE64_DECODE */ +# define USE_X509/**< Enable minimal X.509 support. */ +# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ +# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ +/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ +/**< Support extra distinguished name attributes not mentioned in RFC 5280. */ +/* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ +/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ +/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ + +/** + @security SHA-1 based signatures are insecure, as SHA-1 can no longer + be considered collision resistant (https://shattered.it/static/shattered.pdf). + Enable if compatibility with old certificates is required. + */ +/* #define ENABLE_SHA1_SIGNED_CERTS */ + +/**< @security Allow parsing of locally trusted v1 root certs? */ +/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */ +/** + When parsing certificates, always also retain the unparsed DER data. + Enabling this has the same effect as setting the + CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call. + */ +/* #define ALWAYS_KEEP_CERT_DER */ +/** + Always attempt to match expectedName with the subject CN, even if + a supported, but non-matching subjectAltName was presented. + The default behaviour is to check the CN only when no supported SAN + was presented, in accordance with Section 6.4.4 of RFC 6125. + */ +/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */ +/* #define USE_CRL *//***< @pre USE_FULL_CERT_PARSE */ +# ifdef USE_CRL +/** + Allow CRL authentication to succeed even when signer CA's cert does not + have the keyUsage extension and thus no cRLSign bit. + Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension + and the cRLSign bit. + */ +/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */ +# endif +/** + Enable OCSP response and request handling. +*/ +/* #define USE_OCSP *//**< @pre USE_SHA1 */ +# ifdef USE_OCSP +# define USE_OCSP_RESPONSE +# elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) +/** + Enable parsing and writing of OCSP responses. This is enough + to support OCSP stapling. +*/ +/* #define USE_OCSP_RESPONSE *//**< @pre USE_SHA1 */ +#endif /* USE_OCSP */ + +/******************************************************************************/ +/** + Various PKCS standards support + */ +# define USE_PRIVATE_KEY_PARSING +/* #define USE_PKCS5 *//**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */ +/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */ +/* #define USE_PBKDF1 */ +/* #define USE_PKCS8 *//* Alternative private key storage format */ +/* #define USE_PKCS12 *//**< @pre USE_PKCS8 */ +/* #define USE_PKCS1_OAEP *//* OAEP padding algorithm */ +# define USE_PKCS1_PSS/* PSS padding algorithm */ + +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +/* #define USE_BASE64_DECODE *//* Allow decoding Base64-encoded data. */ +/* #define USE_PEM_DECODE *//* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + +#endif /* _h_PS_CRYPTOCONFIG */ + +/******************************************************************************/ diff --git a/configs/tls13-minimal/matrixsslConfig.h b/configs/tls13-minimal/matrixsslConfig.h new file mode 100644 index 0000000..c6e5ec9 --- /dev/null +++ b/configs/tls13-minimal/matrixsslConfig.h @@ -0,0 +1,447 @@ +/** + * @file matrixsslConfig.h + * @version $Format:%h%d$ + * + * Configuration settings for building the MatrixSSL library. + * This configuration is intended to be used in FIPS Mode of operation. + * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and + * to enable the most commonly used cipher suites. + */ +/* + * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSLCONFIG +# define _h_MATRIXSSLCONFIG + +# ifdef __cplusplus +extern "C" { +# endif + +/** + NIST SP 800-52 Rev 1 Conformance. + Guidelines for the Selection, Configuration, and Use of Transport Layer + Security (TLS) Implementations + The key words "shall", "shall not", "should", "should not" and "may" + are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as + "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility + is not relevant. + @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf + */ + +/******************************************************************************/ +/** + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. + */ +/* #define USE_SSL_HANDSHAKE_MSG_TRACE */ + +/** + Informational trace that could help pinpoint problems with TLS/DTLS + connections. + */ +/* #define USE_SSL_INFORMATIONAL_TRACE */ +/* #define USE_DTLS_DEBUG_TRACE */ + +/******************************************************************************/ +/** + Recommended cipher suites. + Define the following to enable various cipher suites + At least one of these must be defined. If multiple are defined, + the handshake negotiation will determine which is best for the connection. + @note Ephemeral ciphersuites offer perfect forward security (PFS) + at the cost of a slower TLS handshake. + */ + +/** TLS 1.3 ciphers */ +# define USE_TLS_AES_128_GCM_SHA256 +/* #define USE_TLS_AES_256_GCM_SHA384 */ +/* #define USE_TLS_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */ +/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ +/** CHACHA20-POLY1305 cipher suites according to RFC 7905. */ +/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ +/* #define USE_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHALL */ +/* #define USE_TLS_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + These cipher suites are secure, but not widely deployed. + */ + +/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */ +/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */ + +/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */ +/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ + +/** Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */ + +/** Pre-Shared Key Ciphers. + NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary + See NIST SP 800-52 Rev 1 Appendix C */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD_NOT */ +/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA384 *//**< @security NIST_SHOULD_NOT */ + +/** Non-Ephemeral ECC DH keys, ECC DSA certificates */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_MAY */ +/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_MAY */ + +/** Non-Ephemeral ECC DH keys, RSA certificates */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */ +/* TLS 1.2 ciphers */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */ +/* #define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */ + +/** Non-Ephemeral RSA keys/certificates */ +/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */ + +/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52 + Rev 1 are not supported by the MatrixSSL / MatrixDTLS. + ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (NIST SP 800-52 Rev 1 "should") + is rarely used cipher suite and is not supported. + Also (NIST SP 800-52 Rev 1 "may") TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_* and TLS_RSA_WITH_AES_*_CCM cipher suites cannot be + enabled as they are not supported. */ + +/******************************************************************************/ +/** + Legacy cipher suites. + These cipher suites have been deprecated, but may be occasionally required + for legacy compatibility. Usage of these cipher suites should be avoided + as these may represent small or moderate risk. + + Note: The RC4 cipher suites below need to disabled according to RFC 7465. +*/ +/* #define USE_SSL_RSA_WITH_RC4_128_SHA *//**< @security NIST_SHALL_NOT */ + +/******************************************************************************/ +/** + Ephemeral key cache support. + If not using cache, new key exchange keys are created for each TLS session. + If using cache, keys are generated initially, and re-used in each + subsequent TLS connection within a given time frame and usage count. + @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE + + @security Do not cache Ephemeral ECC keys as it is against some standards, + including NIST SP 800-56A, when in FIPS 140-2 mode of operation. + */ +# define NO_ECC_EPHEMERAL_CACHE/**< @security NIST_SHALL */ + +/******************************************************************************/ +/** + Configure Support for TLS protocol versions. + Define one of: + USE_TLS_1_2_AND_ABOVE (TLS 1.2 and 1.3) + USE_TLS_1_1_AND_ABOVE (TLS 1.1, 1.2 and 1.3) + USE_TLS_1_0_AND_ABOVE (TLS 1.0, 1.1, 1.2 and 1.3) + @note There is no option for enabling SSL3.0 at this level + */ +/* #define USE_TLS_1_1_AND_ABOVE *//**< @security default 1_1_AND_ABOVE */ +# define USE_TLS_1_2_AND_ABOVE/**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */ +/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */ + +/** Enable support for session resumption in TLS 1.3. */ +# define USE_TLS_1_3_RESUMPTION + +/** TLS 1.3 code has not yet been footprint-optimized. For this reason, + it is possible to separately leave all TLS 1.3 code out of the build + by enabling this. */ +/* #define DISABLE_TLS_1_3 */ + +/******************************************************************************/ +/** + Datagram TLS support. + Enables DTLS in addition to TLS. + @pre TLS_1_1 + */ +/* #define USE_DTLS */ + +/******************************************************************************/ +/** + Compile time support for server or client side SSL + */ +# define USE_CLIENT_SIDE_SSL +# define USE_SERVER_SIDE_SSL + +/******************************************************************************/ +/** + Allow the server to parse SSL 2.0 ClientHello messages even when the + server does not actually support SSL 2.0. As per RFC 5246, E.2: + + "... even TLS servers that do not support SSL 2.0 MAY accept version + 2.0 CLIENT-HELLO messages." + + This option is for compatibility with clients that support + SSL 2.0 but are ready to negotiate a higher version such as TLS 1.0. + Note that enabling this option will only allow parsing of the SSL 2.0 + ClientHellos; it will not enable support for the SSL 2.0 protocol. + Only 32-byte challenges in the SSL 2.0 ClientHello are supported. +*/ +# ifdef USE_SERVER_SIDE_SSL +/* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ +# endif + +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + +/******************************************************************************/ +/** + Client certificate authentication + */ +# define USE_CLIENT_AUTH + +# ifdef USE_CLIENT_AUTH +/** + Enable the handshake_messages signature in the CertificateVerify + protocol message to be signed using an external module. + */ +/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */ +# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING +/** + Compile an example external module that allows the + USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example + client program and sslTest. + */ +/* #define USE_EXT_EXAMPLE_MODULE */ +# endif + +/** + Enable loading of a new client certificate and private key + in response to a CertificateRequest message from a server. This feature + allows the client program to e.g. select a client certificate + whose issuer is included in the server's list of trusted CAs + that was received in the CertificateRequest message. +*/ +/* #define USE_EXT_CLIENT_CERT_KEY_LOADING */ +# endif /* USE_CLIENT_AUTH */ + +/** + Enable if the server should send an empty CertificateRequest message if + no CA files have been loaded + */ +/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */ + +/** + Enabling this define will allow the server to "downgrade" a client auth + handshake to a standard handshake if the client replies to a + CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback + will be called with a NULL cert in this case and the user can determine if + the handshake should continue in a non-client auth state. + */ +/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */ + +/******************************************************************************/ +/** + Allow partial parsing of CA certificate bundles. By default, loading of + CA files via matrixSslLoadRsaKeys, etc. will fail if the bundle contains + a certificate not supported by MatrixSSL's current configuration. When + this define is enabled, the parsing of some CA certificates is allowed fail. + When parsing of a CA cert fails, a dummy psX509Cert_t with will be added + to the CAcerts list. Consult the parseStatus members for details on why + the parsing of a specific certificate failed. + */ +/* #define ALLOW_CA_BUNDLE_PARTIAL_PARSE */ + +/******************************************************************************/ +/** + Enable the Application Layer Protocol Negotiation extension. + Servers and Clients will still have to use the required public API to + set protocols and register application callbacks to negotiate the + protocol that will be tunneled over TLS. + @see ALPN section in the developer's guide for information. + */ +/* #define USE_ALPN */ + +/******************************************************************************/ +/** + Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the + sha1 hash of each CA file to the server for help in server selection. + This extra level of define is to help isolate the SHA1 requirement + */ +/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */ + +/******************************************************************************/ +/** + A client side configuration that requires a server to provide an OCSP + response if the client uses the certitificate status request extension. + The "must staple" terminology is typically associated with certificates + at the X.509 layer but it is a good description of what is being required + of the server at the TLS level. + @pre USE_OCSP_RESPONSE must be enabled at the crypto level and the client + application must use the OCSPstapling session option at run time for this + setting to have any effect + */ +# ifdef USE_OCSP_RESPONSE +# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */ +# endif + +/******************************************************************************/ +/** + Rehandshaking support. + + Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the + protocol defined in RFC 5748 which fixed a critical exploit in + the standard TLS specification. + + @security Looking towards TLS 1.3, which removes re-handshaking, this + feature is disabled by default. + */ +/* #define USE_REHANDSHAKING */ + +/******************************************************************************//** + False Start support for Chrome and Firefox browsers. + @see https://tools.ietf.org/html/rfc7918 + + Some versions of Firefox browser and Chrome browser include support for + False Start. This flag will enable server side support on MatrixSSL + operating as server for client using false start feature. + + @note April 2012: Google has announced this feature will be removed in + version 20 of their browser due to industry compatibility issues. + However because there are other browsers using the feature, this feature + is often recommendable to enable for maximal browser compatibility. + */ +# define USE_SERVER_SIDE_FALSE_START_SUPPORT + +/******************************************************************************/ +/** + If SERVER you may define the number of sessions to cache and how + long a session will remain valid in the cache from first access. + Session caching enables very fast "session resumption handshakes". + + SSL_SESSION_TABLE_SIZE minimum value is 1 + SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0 + + @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0 + however, this will also immediately expire SESSION_TICKETS below. + */ +# ifdef USE_SERVER_SIDE_SSL +# define SSL_SESSION_TABLE_SIZE 32 +# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */ +# endif + +/******************************************************************************/ +/** + Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE + define applies to this method as well as the standard method. The + SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list. + */ +# define USE_STATELESS_SESSION_TICKETS +# define SSL_SESSION_TICKET_LIST_LEN 32 + +/******************************************************************************/ +/** + The initial buffer sizes for send and receive buffers in each ssl_t session. + Buffers are internally grown if more incoming or outgoing data storage is + needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the + buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced + to this size. Most standard SSL handshakes require on the order of 1024 B. + + SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE + */ +# ifndef USE_DTLS +# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */ +# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */ +# else +/******************************************************************************/ +/** + The Path Maximum Transmission Unit is the largest datagram that can be + sent or recieved. It is beyond the scope of DTLS to negotiate this value + so make sure both sides have agreed on this value. This is an enforced + limitation in MatrixDTLS so connections will not succeed if a peer has a + PTMU set larger than this value. + */ +# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */ +# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ +# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */ + +/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ +# endif + +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + +# ifdef __cplusplus +} +# endif + +#endif /* _h_MATRIXCONFIG */ +/******************************************************************************/ diff --git a/configs/tls13/coreConfig.h b/configs/tls13/coreConfig.h index a0e9380..0255323 100644 --- a/configs/tls13/coreConfig.h +++ b/configs/tls13/coreConfig.h @@ -40,61 +40,10 @@ /* Debug and tracing configuration */ /******************************************************************************/ -/** - Select tracing facility. - Default: Use psLogf, which is used in all of MatrixSSL, CL etc. and - allows log redirection. - - On the smallest embedded targets platform using PS_NO_LOGF may provide - footprint benefits but will limit logging capabilities. - */ - -/* Uncomment to use previous generation logging facility: */ -/* #define PS_NO_LOGF */ - -/* When using psLogf, logging messages by default go to the binary, but - they are not shown unless enabled by environment variables or - filter loaded with psLogfSetHookEnabledCheck() function. - - Enable macros below to completely remove specified logging class. */ -/* #define PS_NO_LOGF_FATAL */ -/* #define PS_NO_LOGF_ERROR */ -/* #define PS_NO_LOGF_WARNING */ -/* #define PS_NO_LOGF_INFO */ -/* #define PS_NO_LOGF_VERBOSE */ -/* #define PS_NO_LOGF_DEBUG */ -/* #define PS_NO_LOGF_TRACE */ -/* #define PS_NO_LOGF_CALL_TRACE */ - -/* MatrixSSL contains extensive tracing capabilities. The lines below - disable trace and call trace message levels, unless debug build. - Omitting the messages will improve performance and create smaller - executables with a degradation in debugging capabilities. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_TRACE -# define PS_NO_LOGF_TRACE -# endif -# ifndef PS_NO_LOGF_CALL_TRACE -# define PS_NO_LOGF_CALL_TRACE -# endif -# endif - -/* File and line information consumes some storage and may reveal details on - structure of software. This information is omitted from production builds, - but included within "debug build". If you want to include file and line - information also on production builds, disable the lines below. */ -# ifndef DEBUG -# ifndef PS_NO_LOGF_FILELINE -# define PS_NO_LOGF_FILELINE -# endif -# endif - /** Enable various levels of trace. When these option is turned off, messages are silently discarded and their text does not take space in the binary image. - Note: These are legacy configuration, and it is recommended to use - PS_NO_LOGF_* above, unless PS_NO_LOGF is set. */ /* #define USE_CORE_TRACE */ # ifndef NO_CORE_ERROR @@ -104,6 +53,16 @@ # define USE_CORE_ASSERT # endif +/** Allow target file of psTrace output to be chosen with the + PSCORE_DEBUG_FILE and PSCORE_DEBUG_FILE_APPEND environment variables. + By default, stdout is used. Disable to minimize footprint. */ +/* #define USE_TRACE_FILE */ + +/** Experimental, extensible logging facility. Only used by the SL/CL + crypto libraries; not used by the TLS library. Disable to minimize + footprint. */ +/* #define PS_LOGF */ + /******************************************************************************/ /* Other Configurable features */ /******************************************************************************/ @@ -116,6 +75,11 @@ /* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */ # endif +/** Enable to disable file IO related APIs, such as psGetFileBuf + and psParseCertFile. This helps to minimize footprint when no file IO + is needed. */ +/* #define NO_FILE_SYSTEM */ + /** Include the psCoreOsdepMutex family of APIs diff --git a/configs/tls13/cryptoConfig.h b/configs/tls13/cryptoConfig.h index 0e0944c..d3ac379 100644 --- a/configs/tls13/cryptoConfig.h +++ b/configs/tls13/cryptoConfig.h @@ -228,10 +228,14 @@ # define USE_X509/**< Enable minimal X.509 support. */ # define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */ # define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */ +/**< Support the certificatePolicy, policyMappings and policyContrainsts X.509 extensions. */ +/* #define USE_CERT_POLICY_EXTENSIONS */ /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */ /**< Support extra distinguished name attributes not mentioned in RFC 5280. */ /* #define USE_EXTRA_DN_ATTRIBUTES */ +/**< Allow ASN.1 BMPString string type in DN Attributes. */ +/* #define USE_ASN_BMPSTRING_DN_ATTRIBS */ /* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */ /* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */ @@ -273,13 +277,12 @@ /* #define USE_OCSP *//**< @pre USE_SHA1 */ # ifdef USE_OCSP # define USE_OCSP_RESPONSE -# define USE_OCSP_REQUEST # elif defined(USE_X509) && defined(USE_SHA1) && defined(USE_CERT_PARSE) /** Enable parsing and writing of OCSP responses. This is enough to support OCSP stapling. */ -# define USE_OCSP_RESPONSE /**< @pre USE_SHA1 */ +# define USE_OCSP_RESPONSE/**< @pre USE_SHA1 */ #endif /* USE_OCSP */ /******************************************************************************/ @@ -295,6 +298,12 @@ # define USE_PKCS1_OAEP/* OAEP padding algorithm */ # define USE_PKCS1_PSS/* PSS padding algorithm */ +# ifdef USE_PRIVATE_KEY_PARSING +/* USE_PRIVATE_KEY_PARSING enables decoding of DER-encoded keys and certs. For PEM there is a separate define. */ +# define USE_BASE64_DECODE/* Allow decoding Base64-encoded data. */ +# define USE_PEM_DECODE/* Allow decoding PEM-encoded data. @pre USE_BASE64_DECODE. */ +# endif + #endif /* _h_PS_CRYPTOCONFIG */ /******************************************************************************/ diff --git a/configs/tls13/matrixsslConfig.h b/configs/tls13/matrixsslConfig.h index 6c7cea3..f39c60c 100644 --- a/configs/tls13/matrixsslConfig.h +++ b/configs/tls13/matrixsslConfig.h @@ -55,12 +55,14 @@ extern "C" { /******************************************************************************/ /** - Show which SSL messages are created and parsed + Show which handshake messages are created and parsed. Also enables + TLS level error message logging. */ /* #define USE_SSL_HANDSHAKE_MSG_TRACE */ /** - Informational trace that could help pinpoint problems with SSL connections + Informational trace that could help pinpoint problems with TLS/DTLS + connections. */ /* #define USE_SSL_INFORMATIONAL_TRACE */ /* #define USE_DTLS_DEBUG_TRACE */ @@ -250,6 +252,14 @@ extern "C" { /* #define ALLOW_SSLV2_CLIENT_HELLO_PARSE */ # endif +/** + Allow more lenient TLS record header version matching: allow the + record header version to be an TLS version when TLS has been + negotiated. This does not affect the processing of the ClientHello + record, since it is already exempt from version matching. +*/ +/* #define USE_LENIENT_TLS_RECORD_VERSION_MATCHING */ + /******************************************************************************/ /** Client certificate authentication @@ -424,6 +434,11 @@ extern "C" { /* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */ # endif +/* Use a buffered instead of continuously updated HS hash. + This avoids the need for multiple parallel hash context, one for + each supported hash algorithm. */ +/* #define USE_BUFFERED_HS_HASH */ + # ifdef __cplusplus } # endif diff --git a/core/include/psLog.h b/core/include/psLog.h index 4338f8a..f5f3dbe 100644 --- a/core/include/psLog.h +++ b/core/include/psLog.h @@ -45,12 +45,8 @@ # endif #endif /* _h_PS_CORECONFIG */ -# ifndef PS_NO_LOGF -/* Define a common logging framework. - If you want to use previous MatrixSSL logging facilities only, - please add #define PS_NO_LOGF - to coreConfig.h. -*/ +# ifdef PS_LOGF +/* Experimental a common logging framework. */ #include "psPrnf.h" #ifdef __GNUC__ @@ -550,7 +546,7 @@ psLogfSetHookPrintfFunction_t psLogfSetHookPrintf( #define PS_LOGF_FATAL_LN(...) \ do { /* fatal error logging not available */ } while(0) -# endif /* PS_NO_LOGF */ +# endif /* PS_LOGF */ #endif /* _h_PS_LOG */ diff --git a/core/makefiles/detect-and-rules.mk b/core/makefiles/detect-and-rules.mk index 158d0e9..a5b1e71 100644 --- a/core/makefiles/detect-and-rules.mk +++ b/core/makefiles/detect-and-rules.mk @@ -12,6 +12,9 @@ CORE_PATH:=$(patsubst %/,%/..,$(dir $(lastword $(MAKEFILE_LIST)))) include $(CORE_PATH)/Makefile.inc +#ifdef USE_ROT_CRYPTO +#endif + # Allow extra CFLAGS, CPPFLAGS and LDFLAGS to be used. CFLAGS_DEBUGGABLE=$(DEBUGGABLE) CPPFLAGS_DEBUGGABLE=$(DEBUGGABLE) @@ -25,6 +28,13 @@ CPPFLAGS += $(CPPFLAGS_STANDARD) $(CPPFLAGS_PLATFORM) $(CPPFLAGS_ADDITIONAL) $(C BUILD:=release ##< Release build strips binary and optimizes #BUILD:=debug ##< Debug build keeps debug symbols and disables compiler optimizations. Assembly language optimizations remain enabled +ifneq '$(MATRIX_OPTIMIZE)' '' +BUILD:=release +endif +ifneq '$(MATRIX_OPTIMIZE_FOOTPRINT)' '' +BUILD:=release +endif + #------------------------------------------------------------------------------- ## Makefile variables that are read by this file. # @param[in] $(MATRIXSSL_ROOT) Must be set to root MatrixSSL directory @@ -47,7 +57,7 @@ BUILD:=release ##< Release build strips binary and optimizes # @param[out] $(STRIP) Set to the executable to use to strip debug symbols from executables # @param[out] $(STROPS) Human readable description of relevant MatrixSSL compile options. # @param[out] $(O) Set to the target platform specific object file extension -# @param[out] $(A) Set to the target phatform specific static library (archive) file extension +# @param[out] $(A) Set to the target platform specific static library (archive) file extension # @param[out] $(E) Set to the target platform specific executable file extension # @param[out] $(OBJS) Set to the list of objects that is to be built @@ -151,6 +161,9 @@ ifndef MATRIX_DEBUG ifneq (,$(findstring -none,$(CCARCH))) OPT:=-Os -Wall # Compile bare-metal for size endif + ifneq '$(MATRIX_OPTIMIZE_FOOTPRINT)' '' + OPT:=-Os -Wall + endif STRIP:=strip endif CFLAGS+=$(OPT) $(C_STD) @@ -408,6 +421,7 @@ LIBCORE_S_A=$(CORE_PATH)/libcore_s$(A) LIBCRYPT_S_A=$(MATRIXSSL_ROOT)/crypto/libcrypt_s$(A) LIBCMS_S_A=$(MATRIXSSL_ROOT)/crypto/cms/libcms_s$(A) LIBSSL_S_A=$(MATRIXSSL_ROOT)/matrixssl/libssl_s$(A) +LIBROT_S_A=$(MATRIXSSL_ROOT)/crypto-rot/rot/lib/libdriver_val_up$(A) # Optional external libraries LIBZ=-lz diff --git a/core/makefiles/rules.mk b/core/makefiles/rules.mk index 5c9cb98..4e52be9 100644 --- a/core/makefiles/rules.mk +++ b/core/makefiles/rules.mk @@ -66,6 +66,10 @@ OPT= endif endif +ifneq '$(MATRIX_OPTIMIZE_FOOTPRINT)' '' +OPT=-Os +endif + #Override CFLAGS_OPTIMIZE with OPT if specified ifneq '$(filter file override command automatic,$(origin OPT))' '' CFLAGS_OPTIMIZE=$(OPT) diff --git a/core/osdep/POSIX/osdep.c b/core/osdep/POSIX/osdep.c index 7830da2..9cd8254 100644 --- a/core/osdep/POSIX/osdep.c +++ b/core/osdep/POSIX/osdep.c @@ -496,6 +496,9 @@ void osdepTraceClose(void) FILE *_psGetTraceFile(void) { +#ifndef USE_TRACE_FILE + return stdout; +#else static FILE *tracefile = NULL; #ifdef USE_MULTITHREADING static pthread_mutex_t tracefile_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -563,6 +566,7 @@ FILE *_psGetTraceFile(void) #endif /* USE_MULTITHREADING */ } return tracefile; +#endif /* USE_TRACE_FILE */ } void _psTrace(const char *msg) diff --git a/core/osdep/POSIX/psLog.c b/core/osdep/POSIX/psLog.c index d6a15ce..644a79f 100644 --- a/core/osdep/POSIX/psLog.c +++ b/core/osdep/POSIX/psLog.c @@ -1,7 +1,7 @@ #define _POSIX_C_SOURCE 200112L #include "psLog.h" -#ifndef PS_NO_LOGF +#ifdef PS_LOGF #include "osdep_stdarg.h" #include "osdep_stdio.h" @@ -704,4 +704,4 @@ void psLogfDisable(const char *module_or_level) psLogfFlush(); } -#endif /* PS_NO_LOGF */ +#endif /* PS_LOGF */ diff --git a/core/osdep/include/osdep-types.h b/core/osdep/include/osdep-types.h index 0ec4dc0..9ea9d1b 100644 --- a/core/osdep/include/osdep-types.h +++ b/core/osdep/include/osdep-types.h @@ -53,18 +53,24 @@ # if defined(__linux__) /* Linux and Android */ # define POSIX # define LINUX -# define MATRIX_USE_FILE_SYSTEM +# ifndef NO_FILE_SYSTEM +# define MATRIX_USE_FILE_SYSTEM +# endif # elif defined(__APPLE__) && defined(__MACH__) /* Mac OS X */ # define POSIX # define OSX # define HAVE_NATIVE_INT64 -# define MATRIX_USE_FILE_SYSTEM +# ifndef NO_FILE_SYSTEM +# define MATRIX_USE_FILE_SYSTEM +# endif # elif defined(_WIN32) /* Windows */ # ifndef WIN32 # define WIN32 # endif # define HAVE_NATIVE_INT64 -# define MATRIX_USE_FILE_SYSTEM +# ifndef NO_FILE_SYSTEM +# define MATRIX_USE_FILE_SYSTEM +# endif # endif /* For others such as FREERTOS, define in build system */ diff --git a/core/osdep/include/osdep_unistd.h b/core/osdep/include/osdep_unistd.h index d683af1..86ed8da 100644 --- a/core/osdep/include/osdep_unistd.h +++ b/core/osdep/include/osdep_unistd.h @@ -61,6 +61,11 @@ #define Sleep sleep #endif /* Sleep */ +/* Macro that provides Close, which is macro wrapper for close. */ +#ifndef Close +#define Close close +#endif /* Close */ + #endif /* system that usually has unistd.h. */ #endif /* OSDEP_UNISTD_H_DEFINED */ diff --git a/core/src/corelib_date.c b/core/src/corelib_date.c index eec56ef..3332d34 100644 --- a/core/src/corelib_date.c +++ b/core/src/corelib_date.c @@ -235,6 +235,7 @@ PSPUBLIC int32 psBrokenDownTimeAdd(psBrokenDownTime_t *res, int32 offset) res->tm_wday %= 7; res->tm_hour %= 24; } + /* Do month days, months & years as a loop. */ while (res->tm_mday > mdays(res)) { diff --git a/core/src/psUtil.c b/core/src/psUtil.c index 14b694b..1068c2e 100644 --- a/core/src/psUtil.c +++ b/core/src/psUtil.c @@ -112,11 +112,12 @@ char *psStrdupN(const char *string) { return NULL; } - len = psStrlen(string) + 1; - new_str = psMallocN(len); + len = psStrlen(string); + new_str = psMallocN(len + 1); if (new_str) { psMemcpy(new_str, string, len); + new_str[len] = 0; } return new_str; } diff --git a/crypto/Makefile b/crypto/Makefile index 60b4d42..72cbe2e 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -19,6 +19,7 @@ SRC:=\ symmetric/idea.c \ symmetric/rc2.c \ symmetric/seed.c \ + digest/hash.c \ digest/sha256_standalone.c \ digest/sha1.c \ digest/sha256.c \ diff --git a/crypto/common/alg_info.c b/crypto/common/alg_info.c index 0c766b1..060f361 100644 --- a/crypto/common/alg_info.c +++ b/crypto/common/alg_info.c @@ -85,6 +85,7 @@ psResSize_t psSigAlgToHashLen(int32_t sigAlg) return MD5_HASH_SIZE; case OID_SHA1_RSA_SIG: case OID_SHA1_ECDSA_SIG: + case OID_SHA1_DSA_SIG: return SHA1_HASH_SIZE; case OID_SHA256_RSA_SIG: case OID_SHA256_ECDSA_SIG: @@ -121,6 +122,8 @@ psResSize_t psPssHashAlgToHashLen(int32_t pssHashAlg) { switch(pssHashAlg) { + case PKCS1_MD5_ID: + return MD5_HASH_SIZE; case PKCS1_SHA1_ID: return SHA1_HASH_SIZE; case PKCS1_SHA256_ID: @@ -389,11 +392,28 @@ uint16_t psGetNamedSigAlgId(const char *name) return 0; } +/* Do we recognize namedGroup as an ECDHE/X25519 curve? */ psBool_t psIsEcdheGroup(uint16_t namedGroup) { - if (namedGroup == namedgroup_secp256r1 || + /* Refuse to recognize some of the rarer curves unless + enabled in cryptoConfig.h */ + if (namedGroup == namedgroup_secp192r1 || + namedGroup == namedgroup_secp256r1 || namedGroup == namedgroup_secp384r1 || namedGroup == namedgroup_secp521r1 || +# ifdef USE_BRAIN521R1 + namedGroup == namedgroup_brain521r1 || +# endif +# ifdef USE_BRAIN384R1 + namedGroup == namedgroup_brain384r1 || +# endif +# ifdef USE_BRAIN256R1 + namedGroup == namedgroup_brain256r1 || + +# endif +# ifdef USE_SECP224R1 + namedGroup == namedgroup_secp224r1 || +# endif namedGroup == namedgroup_x25519) { return PS_TRUE; @@ -411,6 +431,8 @@ psBool_t psIsSigAlgSupported(uint16_t sigAlg) signature generation. */ psBool_t canUsePss = PS_FALSE; + (void)canUsePss; + PS_VARIABLE_SET_BUT_UNUSED(isNonFips); #ifdef USE_PKCS1_PSS diff --git a/crypto/cryptoApi.h b/crypto/cryptoApi.h index 47408e4..03a0f44 100644 --- a/crypto/cryptoApi.h +++ b/crypto/cryptoApi.h @@ -341,6 +341,20 @@ PSPUBLIC void psDes3Clear(psDes3_t *ctx); /* Hash Digest Algorithms */ +typedef struct +{ + uint32_t flags; +} psHashOpts_t; + +psRes_t psHashInit(psDigestContext_t *ctx, + int32_t hashAlgId, + psHashOpts_t *opts); +psRes_t psHashUpdate(psDigestContext_t *ctx, + const unsigned char *data, + psSizeL_t dataLen); +psRes_t psHashFinal(psDigestContext_t *ctx, + unsigned char *hashOut); + # ifdef USE_MD5 /******************************************************************************/ static inline void psMd5PreInit(psMd5_t *md5) @@ -625,7 +639,6 @@ PSPUBLIC void psHmacSha384Final(psHmacSha384_t * ctx, unsigned char hash[SHA384_HASHLEN]); # endif -# ifdef USE_PEM_DECODE typedef enum { PEM_TYPE_ANY = 0, PEM_TYPE_KEY, @@ -634,6 +647,7 @@ typedef enum { PEM_TYPE_CERTIFICATE } psPemType_t; +# ifdef USE_PEM_DECODE PSPUBLIC int32_t psPemFileToDer(psPool_t *pool, @@ -665,6 +679,8 @@ psPemCertBufToList(psPool_t *pool, psSizeL_t len, psList_t **x509certList); +# endif /* USE_PEM_DECODE */ + PSPUBLIC int32_t psPemTryDecode(psPool_t *pool, const unsigned char *in, @@ -674,8 +690,6 @@ psPemTryDecode(psPool_t *pool, unsigned char **out, psSizeL_t *outlen); -# endif /* USE_PEM_DECODE */ - /******************************************************************************/ /* Private Key Parsing diff --git a/crypto/cryptoCheck.h b/crypto/cryptoCheck.h index f41859a..d01d347 100644 --- a/crypto/cryptoCheck.h +++ b/crypto/cryptoCheck.h @@ -127,14 +127,6 @@ # error "Enable USE_CERT_GEN in cryptoConfig.h for USE_OCSP_REQUEST" # endif -/* Currently enable PEM decoding whenever private key parsing is enabled.*/ -# if defined(USE_PRIVATE_KEY_PARSING) -# define USE_PEM_DECODE -# ifndef USE_BASE64_DECODE -# define USE_BASE64_DECODE -# endif -# endif - #endif /* _h_PS_CRYPTOCHECK */ /******************************************************************************/ diff --git a/crypto/cryptoImpl.h b/crypto/cryptoImpl.h index 7268c7a..098588f 100644 --- a/crypto/cryptoImpl.h +++ b/crypto/cryptoImpl.h @@ -36,19 +36,8 @@ # define _h_PS_CRYPTOIMPL # define PS_CRYPTO_IMPLEMENTATION 1 -# ifndef PS_LOGF_WITH_PRNF -# include "cryptoApi.h" -# include "osdep.h" -# include "psUtil.h" -# else -/* Note: The inclusion order of headers is very important when - PS_LOGF_WITH_PRNF is defined. */ -# include "coreApi.h" -# include "osdep.h" -# include "psPrnf.h" -# include "psLog.h" -# include "cryptoApi.h" -# include "cryptolib.h" -# endif +# include "cryptoApi.h" +# include "osdep.h" +# include "psUtil.h" #endif /* _h_PS_CRYPTOIMPL */ diff --git a/crypto/cryptolib.h b/crypto/cryptolib.h index 555e388..2268f7d 100644 --- a/crypto/cryptolib.h +++ b/crypto/cryptolib.h @@ -89,23 +89,6 @@ extern const psEccCurve_t eccCurves[]; /* Crypto trace */ -# ifdef USE_PS_LOGF_COMMON -# define psTraceCrypto(x) PS_LOGF_COMMON(Log_Trace, PS_CRYPTO, PS_LOGF_FMT, \ - PS_LOGF_FILELINE, "%s", x) -# define psTraceIntCrypto(x, i) PS_LOGF_COMMON(Log_Trace, PS_CRYPTO, \ - PS_LOGF_FMT, \ - PS_LOGF_FILELINE, x, i) -# define psTraceStrCrypto(x, s) PS_LOGF_COMMON(Log_Trace, PS_CRYPTO, \ - PS_LOGF_FMT, \ - PS_LOGF_FILELINE, x, s) -# define psTracePtrCrypto(x, p) PS_LOGF_COMMON(Log_Trace, PS_CRYPTO, \ - PS_LOGF_FMT, \ - PS_LOGF_FILELINE, x, p) -# define psTracefCrypto(x, ...) PS_LOGF_COMMON(Log_Trace, PS_CRYPTO, \ - PS_LOGF_FMT, \ - PS_LOGF_FILELINE, x, \ - __VA_ARGS__) -# else # ifndef USE_CRYPTO_TRACE # define psTraceCrypto(x) # define psTraceStrCrypto(x, y) @@ -117,9 +100,8 @@ extern const psEccCurve_t eccCurves[]; # define psTraceStrCrypto(x, y) _psTraceStr(x, y) # define psTraceIntCrypto(x, y) _psTraceInt(x, y) # define psTracePtrCrypto(x, y) _psTracePtr(x, y) -# define psTracefCrypto(x, y) /* Only available via PS_LOGF_COMMON. */ +# define psTracefCrypto(x, y) # endif /* USE_CRYPTO_TRACE */ -# endif /* PS_LOGF_COMMON */ /******************************************************************************/ /* @@ -454,9 +436,14 @@ extern int32_t psGetPrngLocked(unsigned char *bytes, psSize_t size, # define sigalg_ecdsa_sha1 0x0203 /* TLS 1.3 NamedGroup values. */ +# define namedgroup_secp192r1 0x0013 +# define namedgroup_secp224r1 0x0015 # define namedgroup_secp256r1 0x0017 # define namedgroup_secp384r1 0x0018 # define namedgroup_secp521r1 0x0019 +# define namedgroup_brain256r1 0x001a +# define namedgroup_brain384r1 0x001b +# define namedgroup_brain521r1 0x001c # define namedgroup_x25519 0x001d # define namedgroup_x448 0x001e # define namedgroup_ffdhe2048 0x0100 diff --git a/crypto/digest/digest.h b/crypto/digest/digest.h index 4b27647..80523a9 100644 --- a/crypto/digest/digest.h +++ b/crypto/digest/digest.h @@ -75,35 +75,42 @@ # ifdef USE_OPENSSL_CRYPTO # include "digest_openssl.h" # endif +# ifdef USE_ROT_CRYPTO +# include "digest_rot.h" +# endif /******************************************************************************/ -typedef union +typedef struct { + union + { # ifdef USE_SHA1 - psSha1_t sha1; + psSha1_t sha1; # endif # ifdef USE_MD5SHA1 - psMd5Sha1_t md5sha1; + psMd5Sha1_t md5sha1; # endif # ifdef USE_SHA256 - psSha256_t sha256; + psSha256_t sha256; # endif # ifdef USE_SHA384 - psSha384_t sha384; + psSha384_t sha384; # endif # ifdef USE_SHA512 - psSha512_t sha512; + psSha512_t sha512; # endif # ifdef USE_MD5 - psMd5_t md5; + psMd5_t md5; # endif # ifdef USE_MD2 - psMd2_t md2; + psMd2_t md2; # endif # ifdef USE_MD4 - psMd4_t md4; + psMd4_t md4; # endif + } u; + int32_t hashAlgId; } psDigestContext_t; typedef struct diff --git a/crypto/digest/hash.c b/crypto/digest/hash.c new file mode 100644 index 0000000..55d7ce2 --- /dev/null +++ b/crypto/digest/hash.c @@ -0,0 +1,124 @@ +/** + * @file hash.c + * @version $Format:%h%d$ + * + * Algorithm-independent psHash API implementation. + * Supports SHA-256, SHA-384 and SHA-512. + */ +/* + * Copyright (c) 2013-2019 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#include "../cryptoImpl.h" + +psRes_t psHashInit(psDigestContext_t *ctx, + int32_t hashAlgId, + psHashOpts_t *opts) +{ + (void) opts; + + Memset(ctx, 0, sizeof(*ctx)); + ctx->hashAlgId = hashAlgId; + + switch (ctx->hashAlgId) + { + case OID_SHA256_ALG: + return psSha256Init(&ctx->u.sha256); + break; +# ifdef USE_SHA384 + case OID_SHA384_ALG: + return psSha384Init(&ctx->u.sha384); + break; +# endif +# ifdef USE_SHA512 + case OID_SHA512_ALG: + return psSha512Init(&ctx->u.sha512); + break; +# endif + default: + psTraceIntCrypto("Unsupported hash len in psHashInit: %zu\n", + ctx->hashAlgId); + return PS_UNSUPPORTED_FAIL; + } + + return PS_SUCCESS; +} + +psRes_t psHashUpdate(psDigestContext_t *ctx, + const unsigned char *data, + psSizeL_t dataLen) +{ + switch (ctx->hashAlgId) + { + case OID_SHA256_ALG: + psSha256Update(&ctx->u.sha256, data, dataLen); + break; +# ifdef USE_SHA384 + case OID_SHA384_ALG: + psSha384Update(&ctx->u.sha384, data, dataLen); + break; +# endif +# ifdef USE_SHA512 + case OID_SHA512_ALG: + psSha512Update(&ctx->u.sha512, data, dataLen); + break; +# endif + default: + psTraceIntCrypto("Unsupported hash len in psHashUpdate: %zu\n", + ctx->hashAlgId); + return PS_UNSUPPORTED_FAIL; + } + + return PS_SUCCESS; +} + +psRes_t psHashFinal(psDigestContext_t *ctx, + unsigned char *hashOut) +{ + switch (ctx->hashAlgId) + { + case OID_SHA256_ALG: + psSha256Final(&ctx->u.sha256, hashOut); + break; +# ifdef USE_SHA384 + case OID_SHA384_ALG: + psSha384Final(&ctx->u.sha384, hashOut); + break; +# endif +# ifdef USE_SHA512 + case OID_SHA512_ALG: + psSha512Final(&ctx->u.sha512, hashOut); + break; +# endif + default: + psTraceIntCrypto("Unsupported hash len in psHashFinal: %zu\n", + ctx->hashAlgId); + return PS_UNSUPPORTED_FAIL; + } + + return PS_SUCCESS; +} diff --git a/crypto/digest/hkdf.c b/crypto/digest/hkdf.c index 7cc7feb..a9af124 100644 --- a/crypto/digest/hkdf.c +++ b/crypto/digest/hkdf.c @@ -36,7 +36,6 @@ #ifdef USE_HKDF #define HKDF_MAX_INFO_LEN 80 -#define MIN(a, b) ((a) < (b) ? (a) : (b)) //#define DEBUG_HKDF int32_t psHkdfExpand(psCipherType_e hmacAlg, diff --git a/crypto/keyformat/asn1.c b/crypto/keyformat/asn1.c index b80d3fd..67769f2 100644 --- a/crypto/keyformat/asn1.c +++ b/crypto/keyformat/asn1.c @@ -427,6 +427,10 @@ int32_t getAsnAlgorithmIdentifier(const unsigned char **pp, psSizeL_t size, @param[out] oid Caller allocated array to receive OID, of at least MAX_OID_LEN elements. @return Number of OID elements written to 'oid', 0 on error. + + @note This function has been deprecated, prefer asnCopyOid(), which + is not limited to to format x.y.z(1).z(2).z(3) ...; + where y <= 2 and x <= 39, and z(n) is less than 2**28. */ uint8_t asnParseOid(const unsigned char *der, psSizeL_t derlen, uint32_t oid[MAX_OID_LEN]) @@ -488,6 +492,112 @@ uint8_t asnParseOid(const unsigned char *der, psSizeL_t derlen, return 0; } +/******************************************************************************/ +/** + Copy ASN.1 DER encoded OBJECT bytes into an OID array. + @param[in] der Pointer to start of OBJECT encoding. + @param[in] derlen Number of bytes pointed to by 'der'. + @param[out] oid Caller allocated array to receive OID, of + at least MAX_OID_BYTES bytes. (Represented as psAsnOid_t type.) + @return Number of OID elements written to 'oid', 0 on error. + + @note The return value is the number of segments in OID presented as a + string, not number of bytes. This is for compatibility with + asnParseOid(). + It is not recommended to rely on return value, except for + determining an error. asn1.h defines MAX_OID_BYTES, which + sets limit on how long OID can be decoded. + */ +uint8_t asnCopyOid(const unsigned char *der, psSizeL_t derlen, + psAsnOid_t oid) +{ + int len; + psSizeL_t i; + unsigned char ch = 0; + + /* Check input is not too short or too long. */ + if (derlen < 1 || derlen > MAX_OID_BYTES - 2) + { + oid[0] = 0; /* zeroize identifier. */ + oid[1] = 0; /* and length. */ + return 0; + } + + oid[0] = (unsigned char) ASN_OID; + oid[1] = (unsigned char) derlen; + + /* First encoding produces two numbers. Therefore start with len=1. */ + len = 1; + + for(i = 0; i < derlen; i++) + { + /* Copy and count non-continuation bytes. */ + ch = der[i]; + len += (ch >> 7) ^ 1; /* Increment count for all bytes 0...0x7f. */ + oid[2 + i] = ch; + } + + /* fail if the last sequence was not properly terminated. */ + if (ch >= 0x80) + { + return 0; + } + + return len; +} + +psSizeL_t asnOidLenBytes(psAsnOid_t oid) +{ + uint8_t id; + uint8_t len_encoded; + unsigned int len; + + id = oid[0]; + len_encoded = oid[1]; + len = len_encoded + 2; + + if (id != ASN_OID || len > MAX_OID_BYTES) + { + return (uint8_t) 0; + } + + return len; +} + +psSizeL_t psAsnWriteOid(psAsnOid_t oid, + unsigned char *der, psSizeL_t dermaxlen) +{ + psSizeL_t len = asnOidLenBytes(oid); + + if (len > 0) + { + if (dermaxlen >= len) + { + Memcpy(der, oid, len); + } + else + { + len = 0; + } + } + return len; +} + +uint8_t asnOidLenSegments(psAsnOid_t oid) +{ + psAsnOid_t oid_copy; + psSizeL_t oid_len; + + oid_len = asnOidLenBytes(oid); + + if (oid_len > 1) + { + return asnCopyOid(&oid[2], oid_len - 2, oid_copy); + } + + return 0; +} + #ifndef MATRIXSSL_NO_OID_DATABASE /* This function uses computed OID sums as base and adds suitable number of @@ -583,7 +693,7 @@ static void checkAsnOidDatabase(int32_t *oi, case OID_MQVSINGLEPASS_SHA1KDF_SCHEME: oid_hex = OID_MQVSINGLEPASS_SHA1KDF_SCHEME_HEX; break; case OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME_HEX; break; case OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME_HEX; break; - case OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME_HEX; break; + case OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME: oid_hex = OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME_HEX; break; default: /* No possible matches: bitwise-add not found constant to OID. */ *oi |= OID_NOT_FOUND; diff --git a/crypto/keyformat/asn1.h b/crypto/keyformat/asn1.h index 51947b3..087ffa2 100644 --- a/crypto/keyformat/asn1.h +++ b/crypto/keyformat/asn1.h @@ -38,6 +38,9 @@ # include "../cryptoApi.h" #endif /* _h_PS_CRYPTOAPI */ +/* Provide deprecation warnings for using deprecated functions. */ +#include "pscompilerdep.h" + #ifndef _h_PS_ASN1 # define _h_PS_ASN1 @@ -106,10 +109,31 @@ extern int32_t getAsnOID(const unsigned char **pp, psSizeL_t size, uint8_t checkForParams, psSize_t *paramLen); # define MAX_OID_LEN 16 /**< Maximum number of segments in OID */ +# define MAX_OID_BYTES 32 /**< Maximum number of bytes in OID. */ +# define MAX_OID_PRINTED_LEN_NAMED 64 /* Maximum length of known OID in + printed form. */ +# define MAX_OID_PRINTED_LEN_BYTES (4 * MAX_OID_BYTES) /* Maximum length of + unknown OIDs. */ +# define MAX_OID_PRINTED_LEN \ + ((MAX_OID_PRINTED_LEN_NAMED) > (MAX_OID_PRINTED_LEN_BYTES) ? \ + (MAX_OID_PRINTED_LEN_NAMED) : (MAX_OID_PRINTED_LEN_BYTES)) + +typedef uint8_t psAsnOid_t[MAX_OID_BYTES]; extern uint8_t asnParseOid(const unsigned char *der, psSizeL_t derlen, - uint32_t oid[MAX_OID_LEN]); + uint32_t oid[MAX_OID_LEN]) PSDEPRECATED_WARN; +/* Copy Oid / Store Oid for later use. */ +extern uint8_t asnCopyOid(const unsigned char *der, psSizeL_t derlen, + psAsnOid_t oid); + +/* Get length of ASN.1 OID as an DER encoded byte sequence. + Will return 0 for failure. */ +extern psSizeL_t asnOidLenBytes(psAsnOid_t oid); + +/* Get length of ASN.1 OID as numbers (or 0 for failure). + Will return 0 for failure. */ +extern uint8_t asnOidLenSegments(psAsnOid_t oid); /* Format OID tag as string for printing. */ extern char *asnFormatOid(psPool_t *pool, @@ -124,6 +148,16 @@ extern char *asnFormatDer(psPool_t *pool, size_t MaxElementOutput, unsigned char Flags); +/* Format psAsnOid_t in dotted notation to provided character array. + Returns a pointer to the array for convenience. + + The function is able to provide symbolic name for some X.509 OIDs. + + Note: This function is implemented by x509.c, but described here as + logically the function belongs with the rest of ASN.1 decoding. */ +const char *psSprintAsnOid(psAsnOid_t oid, + char out[MAX_OID_PRINTED_LEN]); + /******************************************************************************/ #endif /* _h_PS_ASN1 */ diff --git a/crypto/keyformat/asn1fmt.c b/crypto/keyformat/asn1fmt.c index 58bb6bb..326b16c 100644 --- a/crypto/keyformat/asn1fmt.c +++ b/crypto/keyformat/asn1fmt.c @@ -261,17 +261,35 @@ static char *oid_to_string(const unsigned char *oid, size_t oidlen, { return NULL; } - if (oid[2] < 120) + if (oid[2] < 128) { - /* Simple case, [012].x where x < 40. */ - Sprintf(s, "%d.%d", oid[2] / 40, oid[2] % 40); + unsigned char root_arc, arc1; + + /* Single byte case, [01].x or 2.y, where x < 40 or y < 48. */ + arc1 = oid[2]; + if (arc1 >= 80) + { + root_arc = 2; + arc1 -= 80; + } + else if (arc1 >= 40) + { + root_arc = 1; + arc1 -= 40; + } + else + { + root_arc = 0; + } + + Sprintf(s, "%d.%d", root_arc, arc1); s += Strlen(s); oid += 3; oidlen -= 3; } else { - /* Process 2.xxx, where xxx is arbitrary length number >= 40. */ + /* Process 2.xxx, where xxx is arbitrary length number >= 48. */ size_t bytes = oid_part_append(s + 1, oid + 2, oidlen - 2); int i; diff --git a/crypto/keyformat/crl.c b/crypto/keyformat/crl.c index a472b00..396870d 100644 --- a/crypto/keyformat/crl.c +++ b/crypto/keyformat/crl.c @@ -41,15 +41,15 @@ static psMutex_t g_crlTableLock; # endif /* Seems like many CRLs are not adhering to the specification that this - extension be present. That just leaves us with the DN to match against - if we disable this define. Not a big concern to disable it because the - authentication is either going to pass or fail based on sig validation */ + extension be present. That just leaves us with the DN to match against + if we disable this define. Not a big concern to disable it because the + authentication is either going to pass or fail based on sig validation */ /* #define ENFORCE_CRL_AUTH_KEY_ID_EXT */ static void internalFreeCRL(psX509Crl_t *crl); /* The global CRL cache is a linked list of psX509Crl_t structures. A - psX509Crl_t structure represents a single CRL file */ + psX509Crl_t structure represents a single CRL file */ static psX509Crl_t *g_CRL = NULL; @@ -78,35 +78,35 @@ static int internalCRLInsert(psX509Crl_t *crl) if (crl == NULL) { - return 0; + return 0; } if (g_CRL == NULL) { - /* first one */ - g_CRL = crl; - return 1; + /* first one */ + g_CRL = crl; + return 1; } /* append */ next = g_CRL; if (g_CRL == crl) { - return 0; /* no pointer dups */ + return 0; /* no pointer dups */ } while (next->next) { - next = next->next; - if (next == crl) /* no pointer dups */ - { - return 0; - } + next = next->next; + if (next == crl) /* no pointer dups */ + { + return 0; + } } next->next = crl; return 1; } /* Blindly append a CRL to the g_CRL list. Consider psCRL_Update instead. - 1 - Added, 0 - Didn't */ + 1 - Added, 0 - Didn't */ int psCRL_Insert(psX509Crl_t *crl) { int rc; @@ -129,51 +129,51 @@ static int internalShrinkCRLtable(psX509Crl_t *crl, int delete) psX509Crl_t *prev, *curr, *next; /* Return whether or not it was found in the list to help with the - standalone psX509FreeCRL call logic */ + standalone psX509FreeCRL call logic */ if (g_CRL == NULL || crl == NULL) { - return 0; + return 0; } prev = NULL; curr = g_CRL; next = curr->next; while (curr) { - if (curr == crl) - { - if (delete) - { - internalFreeCRL(crl); - } - else - { - curr->next = NULL; - } - if (prev == NULL && next == NULL) - { - /* Only one in list */ - g_CRL = NULL; - } - else if (prev == NULL && next != NULL) - { - /* Removed first one in list */ - g_CRL = next; - } - else if (prev != NULL) - { - /* Removed middle or end */ - prev->next = next; - } - return 1; - } - prev = curr; - curr = curr->next; - if (curr) - { - /* curr can be NULL if we never found crl */ - next = curr->next; - } + if (curr == crl) + { + if (delete) + { + internalFreeCRL(crl); + } + else + { + curr->next = NULL; + } + if (prev == NULL && next == NULL) + { + /* Only one in list */ + g_CRL = NULL; + } + else if (prev == NULL && next != NULL) + { + /* Removed first one in list */ + g_CRL = next; + } + else if (prev != NULL) + { + /* Removed middle or end */ + prev->next = next; + } + return 1; + } + prev = curr; + curr = curr->next; + if (curr) + { + /* curr can be NULL if we never found crl */ + next = curr->next; + } } return 0; } @@ -214,7 +214,7 @@ int psCRL_Delete(psX509Crl_t *crl) } /* Remove all CRLs from g_CRL but don't free the associated memory. Assumes - the user will be using psX509FreeCRL later */ + the user will be using psX509FreeCRL later */ void psCRL_RemoveAll() { psX509Crl_t *curr, *next; @@ -226,9 +226,9 @@ void psCRL_RemoveAll() next = curr->next; while (next) { - next = curr->next; - curr->next = NULL; - curr = next; + next = curr->next; + curr->next = NULL; + curr = next; } g_CRL = NULL; # ifdef USE_MULTITHREADING @@ -248,9 +248,9 @@ void psCRL_DeleteAll() curr = g_CRL; while (curr) { - next = curr->next; - internalShrinkCRLtable(curr, 1); - curr = next; + next = curr->next; + internalShrinkCRLtable(curr, 1); + curr = next; } psAssert(g_CRL == NULL); # ifdef USE_MULTITHREADING @@ -264,24 +264,24 @@ int32 internalCRLmatch(psX509Crl_t *existing, psX509Crl_t *new) /* Same DN? */ if (memcmpct(existing->issuer.hash, new->issuer.hash, SHA1_HASH_SIZE) != 0) { - return -1; + return -1; } # ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT /* Same AuthKeyId? */ if (existing->extensions.ak.keyId == NULL || - new->extensions.ak.keyId == NULL) + new->extensions.ak.keyId == NULL) { - /* Should never be possible */ - return PS_PARSE_FAIL; + /* Should never be possible */ + return PS_PARSE_FAIL; } if (existing->extensions.ak.keyLen != new->extensions.ak.keyLen) { - return -1; + return -1; } if (memcmpct(existing->extensions.ak.keyId, new->extensions.ak.keyId, - new->extensions.ak.keyLen) != 0) + new->extensions.ak.keyLen) != 0) { - return -1; + return -1; } # endif /* Looks like a match */ @@ -289,7 +289,7 @@ int32 internalCRLmatch(psX509Crl_t *existing, psX509Crl_t *new) } /* Remove existing CRL if it exists. Append this one. - FUTURE: Support Delta CRL */ + FUTURE: Support Delta CRL */ int psCRL_Update(psX509Crl_t *crl, int deleteExisting) { psX509Crl_t *curr, *next; @@ -297,32 +297,32 @@ int psCRL_Update(psX509Crl_t *crl, int deleteExisting) if (crl == NULL) { - return 0; + return 0; } # ifdef USE_MULTITHREADING psLockMutex(&g_crlTableLock); # endif /* USE_MULTITHREADING */ - /* Currently no Delta CRL support so replace the CRL if we find the - same issuer. Add otherwise. */ + /* Currently no Delta CRL support so replace the CRL if we find the + same issuer. Add otherwise. */ curr = g_CRL; while (curr) { - next = curr->next; - if (internalCRLmatch(curr, crl) == PS_TRUE) - { - /* Just do a check to make sure the user isn't trying to update - with the exact same CRL pointer */ - if (curr == crl) - { + next = curr->next; + if (internalCRLmatch(curr, crl) == PS_TRUE) + { + /* Just do a check to make sure the user isn't trying to update + with the exact same CRL pointer */ + if (curr == crl) + { # ifdef USE_MULTITHREADING - psUnlockMutex(&g_crlTableLock); + psUnlockMutex(&g_crlTableLock); # endif /* USE_MULTITHREADING */ - return 0; - } - internalShrinkCRLtable(curr, deleteExisting); - break; - } - curr = next; + return 0; + } + internalShrinkCRLtable(curr, deleteExisting); + break; + } + curr = next; } rc = internalCRLInsert(crl); # ifdef USE_MULTITHREADING @@ -332,32 +332,32 @@ int psCRL_Update(psX509Crl_t *crl, int deleteExisting) } /* Helper to see if we have a matching CRL for the given subject cert. So - this means we are looking at the issuer/authority fields of the cert */ + this means we are looking at the issuer/authority fields of the cert */ static int32 internalMatchSubject(psX509Cert_t *cert, psX509Crl_t *CRL) { /* Same DN? */ if (memcmpct(CRL->issuer.hash, cert->issuer.hash, SHA1_HASH_SIZE) != 0) { - return PS_CERT_AUTH_FAIL_DN; + return PS_CERT_AUTH_FAIL_DN; } # ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT /* Same AuthKeyId? */ if (CRL->extensions.ak.keyId == NULL) { - return PS_CERT_AUTH_FAIL_EXTENSION; + return PS_CERT_AUTH_FAIL_EXTENSION; } if (cert->extensions.ak.keyId == NULL) { - return PS_CERT_AUTH_FAIL_EXTENSION; + return PS_CERT_AUTH_FAIL_EXTENSION; } if (CRL->extensions.ak.keyLen != cert->extensions.ak.keyLen) { - return PS_CERT_AUTH_FAIL_EXTENSION; + return PS_CERT_AUTH_FAIL_EXTENSION; } if (memcmpct(CRL->extensions.ak.keyId, cert->extensions.ak.keyId, - CRL->extensions.ak.keyLen) != 0) + CRL->extensions.ak.keyLen) != 0) { - return PS_CERT_AUTH_FAIL_EXTENSION; + return PS_CERT_AUTH_FAIL_EXTENSION; } # endif /* Looks good */ @@ -376,29 +376,29 @@ static int32_t nextUpdateTest(const char *c, int32 timeType) err = psGetBrokenDownGMTime(&timeNow, 0); if (err != PS_SUCCESS) { - return -1; + return -1; } err = psBrokenDownTimeImport( - &nextTime, c, Strlen(c), - timeType == ASN_UTCTIME ? - PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0); + &nextTime, c, Strlen(c), + timeType == ASN_UTCTIME ? + PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0); if (err != PS_SUCCESS) { - return -1; + return -1; } Memcpy(&nextTimeLinger, &nextTime, sizeof nextTimeLinger); err = psBrokenDownTimeAdd(&nextTimeLinger, PS_CRL_TIME_LINGER); if (err != PS_SUCCESS) { - return -1; + return -1; } if (psBrokenDownTimeCmp(&timeNow, &nextTimeLinger) > 0) { - /* nextTime is in past. */ - return -1; + /* nextTime is in past. */ + return -1; } return 0; } @@ -409,30 +409,30 @@ static psX509Crl_t *internalGetCrlForCert(psX509Cert_t *cert) if (cert == NULL) { - return NULL; + return NULL; } curr = g_CRL; while (curr) { - if (internalMatchSubject(cert, curr) == PS_TRUE) - { - /* This is the point where we want to make sure this CRL isn't - expired. We do this by looking at the nextUpdate time and - seeing if we are beyond that */ - if (nextUpdateTest(curr->nextUpdate, curr->nextUpdateType) < 0) - { - /* Got it, but it's expired */ - curr->expired = 1; - } - return curr; - } - curr = curr->next; + if (internalMatchSubject(cert, curr) == PS_TRUE) + { + /* This is the point where we want to make sure this CRL isn't + expired. We do this by looking at the nextUpdate time and + seeing if we are beyond that */ + if (nextUpdateTest(curr->nextUpdate, curr->nextUpdateType) < 0) + { + /* Got it, but it's expired */ + curr->expired = 1; + } + return curr; + } + curr = curr->next; } return NULL; } /* Given a cert, do we have a CRL match for the issuer? - Return if so or NULL if not */ + Return if so or NULL if not */ psX509Crl_t *psCRL_GetCRLForCert(psX509Cert_t *cert) { psX509Crl_t *rc = NULL; @@ -451,70 +451,70 @@ psX509Crl_t *psCRL_GetCRLForCert(psX509Cert_t *cert) /* - -1 no entry in the cache for this cert at all - 0 entry is found and cert is NOT revoked - 1 entry is found and cert IS revoked + -1 no entry in the cache for this cert at all + 0 entry is found and cert is NOT revoked + 1 entry is found and cert IS revoked - A CRL may be passed in if that specific one is being tested. Otherwise - pass NULL to search the g_CRL - */ + A CRL may be passed in if that specific one is being tested. Otherwise + pass NULL to search the g_CRL +*/ int32_t internalCrlIsRevoked(psX509Cert_t *cert, psX509Crl_t *CRL, - psBrokenDownTime_t *bdt) + psBrokenDownTime_t *bdt) { psX509Crl_t *crl; x509revoked_t *entry; if (cert == NULL) { - return -1; + return -1; } if (CRL) { - crl = CRL; + crl = CRL; } else { - if ((crl = internalGetCrlForCert(cert)) == NULL) - { - return -1; - } + if ((crl = internalGetCrlForCert(cert)) == NULL) + { + return -1; + } } if (crl->revoked == NULL) { - /* It is totally reasonable to have a CRL with no revoked certs */ - return 0; + /* It is totally reasonable to have a CRL with no revoked certs */ + return 0; } for (entry = crl->revoked; entry != NULL; entry = entry->next) { - if (cert->serialNumberLen == entry->serialLen) - { - if (memcmpct(cert->serialNumber, entry->serial, entry->serialLen) - == 0) - { - if (bdt) - { - Memcpy(bdt, &entry->revocationDateBDT, - sizeof(psBrokenDownTime_t)); - } - return 1; /* REVOKED! */ - } - } + if (cert->serialNumberLen == entry->serialLen) + { + if (memcmpct(cert->serialNumber, entry->serial, entry->serialLen) + == 0) + { + if (bdt) + { + Memcpy(bdt, &entry->revocationDateBDT, + sizeof(psBrokenDownTime_t)); + } + return 1; /* REVOKED! */ + } + } } return 0; /* never found it. good to go */ } /* - Not sure this needs to be public. The "determine" API is actually - doing the full check + Not sure this needs to be public. The "determine" API is actually + doing the full check - -1 no entry in the cache for this cert at all - 0 entry is found and cert is NOT revoked - 1 entry is found and cert IS revoked + -1 no entry in the cache for this cert at all + 0 entry is found and cert is NOT revoked + 1 entry is found and cert IS revoked - A CRL may be passed in if that specific one is being tested. Otherwise - pass NULL to search the g_CRL - */ + A CRL may be passed in if that specific one is being tested. Otherwise + pass NULL to search the g_CRL +*/ int32_t psCRL_isRevoked(psX509Cert_t *cert, psX509Crl_t *CRL) { int32_t rc; @@ -536,20 +536,20 @@ static int doesCertExpectCRL(psX509Cert_t *cert) { if (cert->extensions.crlDist) { - return PS_TRUE; + return PS_TRUE; } return PS_FALSE; } /* - Uses the psCRL_ format to highlight the use of g_CRL cache + Uses the psCRL_ format to highlight the use of g_CRL cache - Updates the "revokedStatus" member of a psX509Cert_t based on information - from within the cert itself and on the revocation status if a g_CRL entry - is found. - */ + Updates the "revokedStatus" member of a psX509Cert_t based on information + from within the cert itself and on the revocation status if a g_CRL entry + is found. +*/ int32_t psCRL_determineRevokedStatusBDT(psX509Cert_t *cert, - psBrokenDownTime_t *bdt) + psBrokenDownTime_t *bdt) { psX509Crl_t *crl; int expectCrl; @@ -557,7 +557,7 @@ int32_t psCRL_determineRevokedStatusBDT(psX509Cert_t *cert, if (cert == NULL) { - return 0; + return 0; } # ifdef USE_MULTITHREADING psLockMutex(&g_crlTableLock); @@ -567,65 +567,65 @@ int32_t psCRL_determineRevokedStatusBDT(psX509Cert_t *cert, if (crl) { - /* Not going to move along if the CRL has expired */ - if (crl->expired) - { - cert->revokedStatus = CRL_CHECK_CRL_EXPIRED; + /* Not going to move along if the CRL has expired */ + if (crl->expired) + { + cert->revokedStatus = CRL_CHECK_CRL_EXPIRED; # ifdef USE_MULTITHREADING - psUnlockMutex(&g_crlTableLock); + psUnlockMutex(&g_crlTableLock); # endif /* USE_MULTITHREADING */ - return cert->revokedStatus; - } + return cert->revokedStatus; + } - /* If we now have a CRL that is not authenticated yet, let's see if - if our subject happens to have a parent that we can try against. - This case happens if a CRL for an child certificate was - fetched out-of-handshake and now a reconnection attempt is being - made. We now have the parent for that child cert and can - attempt to authenticate */ - if (crl->authenticated == 0 && cert->next) - { - psX509AuthenticateCRL(cert->next, crl, NULL); - } + /* If we now have a CRL that is not authenticated yet, let's see if + if our subject happens to have a parent that we can try against. + This case happens if a CRL for an child certificate was + fetched out-of-handshake and now a reconnection attempt is being + made. We now have the parent for that child cert and can + attempt to authenticate */ + if (crl->authenticated == 0 && cert->next) + { + psX509AuthenticateCRL(cert->next, crl, NULL); + } - /* test it and set the status */ - revoked = internalCrlIsRevoked(cert, crl, bdt); - if (revoked == 0 && crl->authenticated == 1) - { - cert->revokedStatus = CRL_CHECK_PASSED_AND_AUTHENTICATED; + /* test it and set the status */ + revoked = internalCrlIsRevoked(cert, crl, bdt); + if (revoked == 0 && crl->authenticated == 1) + { + cert->revokedStatus = CRL_CHECK_PASSED_AND_AUTHENTICATED; - } - else if (revoked == 0 && crl->authenticated == 0) - { - cert->revokedStatus = CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED; + } + else if (revoked == 0 && crl->authenticated == 0) + { + cert->revokedStatus = CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED; - } - else if (revoked == 1 && crl->authenticated == 1) - { - cert->revokedStatus = CRL_CHECK_REVOKED_AND_AUTHENTICATED; + } + else if (revoked == 1 && crl->authenticated == 1) + { + cert->revokedStatus = CRL_CHECK_REVOKED_AND_AUTHENTICATED; - } - else if (revoked == 1 && crl->authenticated == 0) - { - cert->revokedStatus = CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED; + } + else if (revoked == 1 && crl->authenticated == 0) + { + cert->revokedStatus = CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED; - } - else - { - psTraceCrypto("Unexpected revoked/authenticated combo\n"); - } + } + else + { + psTraceCrypto("Unexpected revoked/authenticated combo\n"); + } } else { - expectCrl = doesCertExpectCRL(cert); - if (expectCrl) - { - cert->revokedStatus = CRL_CHECK_EXPECTED; /* but no entry */ - } - else - { - cert->revokedStatus = CRL_CHECK_NOT_EXPECTED; - } + expectCrl = doesCertExpectCRL(cert); + if (expectCrl) + { + cert->revokedStatus = CRL_CHECK_EXPECTED; /* but no entry */ + } + else + { + cert->revokedStatus = CRL_CHECK_NOT_EXPECTED; + } } # ifdef USE_MULTITHREADING psUnlockMutex(&g_crlTableLock); @@ -648,10 +648,10 @@ static void x509FreeRevoked(x509revoked_t **revoked, psPool_t *pool) while (curr) { - next = curr->next; - psFree(curr->serial, pool); - psFree(curr, pool); - curr = next; + next = curr->next; + psFree(curr->serial, pool); + psFree(curr, pool); + curr = next; } *revoked = NULL; } @@ -662,10 +662,10 @@ static void internalFreeCRL(psX509Crl_t *crl) if (crl == NULL) { - return; + return; } /* test all components for NULL. This is used for freeing during - parse so some might not be there at all */ + parse so some might not be there at all */ pool = crl->pool; psX509FreeDNStruct(&crl->issuer, pool); @@ -682,12 +682,12 @@ void psX509FreeCRL(psX509Crl_t *crl) { if (crl == NULL) { - return; + return; } /* Try to delete from g_CRL list first. Will lock table */ if (psCRL_Delete(crl)) { - return; + return; } internalFreeCRL(crl); } @@ -696,72 +696,72 @@ void psX509FreeCRL(psX509Crl_t *crl) psX509FreeCRL */ static psX509Crl_t *psX509AllocCRL(psPool_t *pool) { - psX509Crl_t *crl; + psX509Crl_t *crl; - if ((crl = psMalloc(pool, sizeof(*crl))) == NULL) + if ((crl = psMalloc(pool, sizeof(*crl))) == NULL) { - return NULL; + return NULL; } - Memset(crl, 0, sizeof(*crl)); - crl->pool = pool; - crl->sigHashLen = sizeof(crl->sigHash); - return crl; + Memset(crl, 0, sizeof(*crl)); + crl->pool = pool; + crl->sigHashLen = sizeof(crl->sigHash); + return crl; } /* Helper for psX509AuthenticateCRL to see if we have a matching CRL for - the given issuer cert */ + the given issuer cert */ static int32 internalMatchIssuer(psX509Cert_t *CA, psX509Crl_t *CRL) { /* Ensure crlSign flag of KeyUsage for the given CA. */ if ( !(CA->extensions.keyUsageFlags & KEY_USAGE_CRL_SIGN)) { # ifndef ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE - /* - Fail if there is no keyUsage extension or the cRLSign flag - is not set. - */ - return PS_CERT_AUTH_FAIL_EXTENSION; + /* + Fail if there is no keyUsage extension or the cRLSign flag + is not set. + */ + return PS_CERT_AUTH_FAIL_EXTENSION; # else - /* - Allow missing cRLSign flag when there is no keyUsage extension. - */ - if (CA->extensions.keyUsageFlags != 0) /* RFC 5280: at least one bit - must be 1 when keyUsage - is present. */ - { - return PS_CERT_AUTH_FAIL_EXTENSION; - } + /* + Allow missing cRLSign flag when there is no keyUsage extension. + */ + if (CA->extensions.keyUsageFlags != 0) /* RFC 5280: at least one bit + must be 1 when keyUsage + is present. */ + { + return PS_CERT_AUTH_FAIL_EXTENSION; + } # endif /* !ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */ } /* Same DN? */ if (memcmpct(CRL->issuer.hash, CA->subject.hash, SHA1_HASH_SIZE) != 0) { - psTraceCrypto("CRL not issued by this CA\n"); - return PS_CERT_AUTH_FAIL_DN; + psTraceCrypto("CRL not issued by this CA\n"); + return PS_CERT_AUTH_FAIL_DN; } # ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT /* Same AuthKeyId? */ if (CRL->extensions.ak.keyId == NULL) { - psTraceCrypto("CRL does not have a AuthKeyId extension\n"); - return PS_CERT_AUTH_FAIL_EXTENSION; + psTraceCrypto("CRL does not have a AuthKeyId extension\n"); + return PS_CERT_AUTH_FAIL_EXTENSION; } if (CA->extensions.sk.id == NULL) { - psTraceCrypto("CA does not have a SubjectKeyId extension\n"); - return PS_CERT_AUTH_FAIL_EXTENSION; + psTraceCrypto("CA does not have a SubjectKeyId extension\n"); + return PS_CERT_AUTH_FAIL_EXTENSION; } if (CRL->extensions.ak.keyLen != CA->extensions.sk.len) { - psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n"); - return PS_CERT_AUTH_FAIL_EXTENSION; + psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n"); + return PS_CERT_AUTH_FAIL_EXTENSION; } if (memcmpct(CRL->extensions.ak.keyId, CA->extensions.sk.id, - CRL->extensions.ak.keyLen) != 0) + CRL->extensions.ak.keyLen) != 0) { - psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n"); - return PS_CERT_AUTH_FAIL_EXTENSION; + psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n"); + return PS_CERT_AUTH_FAIL_EXTENSION; } # endif /* Looks good */ @@ -769,16 +769,16 @@ static int32 internalMatchIssuer(psX509Cert_t *CA, psX509Crl_t *CRL) } /* - NO g_CRL used at all + NO g_CRL used at all - Worth noting that the authenticated state is reset each time this is - called so it shouldn't be called blindly in a loop hoping the status - will come out correctly. + Worth noting that the authenticated state is reset each time this is + called so it shouldn't be called blindly in a loop hoping the status + will come out correctly. - poolUserPtr is for the TMP_PKI pool - */ + poolUserPtr is for the TMP_PKI pool +*/ int32_t psX509AuthenticateCRL(psX509Cert_t *CA, psX509Crl_t *CRL, - void *poolUserPtr) + void *poolUserPtr) { int32 rc; @@ -787,48 +787,48 @@ int32_t psX509AuthenticateCRL(psX509Cert_t *CA, psX509Crl_t *CRL, if (CA == NULL || CRL == NULL) { - return PS_ARG_FAIL; + return PS_ARG_FAIL; } if (CRL->authenticated == 1) { - /* Going to have to assume caller knows what they are doing */ - psTraceCrypto("WARNING: this CRL has already been authenticated\n"); + /* Going to have to assume caller knows what they are doing */ + psTraceCrypto("WARNING: this CRL has already been authenticated\n"); } CRL->authenticated = PS_FALSE; /* A few tests to see if this CA is the true issuer of the CRL */ if ((rc = internalMatchIssuer(CA, CRL)) < 0) { - return rc; + return rc; } /* Perform the signature verification. */ Memset(&opts, 0, sizeof(psVerifyOptions_t)); opts.msgIsDigestInfo = PS_TRUE; rc = psVerifySig(NULL, - CRL->sigHash, CRL->sigHashLen, - CRL->sig, CRL->sigLen, - &CA->publicKey, - CRL->sigAlg, - &verifyResult, - &opts); + CRL->sigHash, CRL->sigHashLen, + CRL->sig, CRL->sigLen, + &CA->publicKey, + CRL->sigAlg, + &verifyResult, + &opts); if (rc != PS_SUCCESS) { - if (verifyResult == PS_FALSE) - { - psTraceCrypto("Unable to verify CRL signature\n"); - return PS_CERT_AUTH_FAIL_SIG; - } - else - { - psTraceIntCrypto("psVerifySig failed: %d\n", rc); - return rc; - } + if (verifyResult == PS_FALSE) + { + psTraceCrypto("Unable to verify CRL signature\n"); + return PS_CERT_AUTH_FAIL_SIG; + } + else + { + psTraceIntCrypto("psVerifySig failed: %d\n", rc); + return rc; + } } if (verifyResult == PS_TRUE) { - CRL->authenticated = PS_TRUE; + CRL->authenticated = PS_TRUE; } return PS_SUCCESS; @@ -842,38 +842,38 @@ int32 psX509GetCRLVersion(const unsigned char *crlBin, int32 crlBinLen) if (crlBin == NULL || crlBinLen <= 0) { - return PS_ARG_FAIL; + return PS_ARG_FAIL; } end = p + crlBinLen; if (getAsnSequence32(&p, (uint32) (end - p), &glen, 0) < 0) { - psTraceCrypto("Initial parse error in psX509GetCRLVersion\n"); - return PS_PARSE_FAIL; + psTraceCrypto("Initial parse error in psX509GetCRLVersion\n"); + return PS_PARSE_FAIL; } if (getAsnSequence32(&p, (uint32) (end - p), &tbsCertLen, 0) < 0) { - psTraceCrypto("Initial parse error in psX509GetCRLVersion\n"); - return PS_PARSE_FAIL; + psTraceCrypto("Initial parse error in psX509GetCRLVersion\n"); + return PS_PARSE_FAIL; } if (end > p && *p == ASN_INTEGER) { - version = 0; - if (getAsnInteger(&p, (uint32) (end - p), &version) < 0 || version < 0) - { - psTraceCrypto("Version parse error in psX509GetCRLVersion.\n"); - return PS_PARSE_FAIL; - } - return (int32) version; + version = 0; + if (getAsnInteger(&p, (uint32) (end - p), &version) < 0 || version < 0) + { + psTraceCrypto("Version parse error in psX509GetCRLVersion.\n"); + return PS_PARSE_FAIL; + } + return (int32) version; } return 1; /* Default version (v2). */ } /* - Parse a CRL. - */ + Parse a CRL. +*/ int32 psX509ParseCRL(psPool_t *pool, psX509Crl_t **crl, unsigned char *crlBin, - int32 crlBinLen) + int32 crlBinLen) { const unsigned char *end, *start, *sigStart, *sigEnd, *revStart, *p = crlBin; int32 oi, version, rc; @@ -885,120 +885,120 @@ int32 psX509ParseCRL(psPool_t *pool, psX509Crl_t **crl, unsigned char *crlBin, if (crlBin == NULL || crlBinLen <= 0) { - return PS_ARG_FAIL; + return PS_ARG_FAIL; } end = p + crlBinLen; /* - CertificateList ::= SEQUENCE { - tbsCertList TBSCertList, - signatureAlgorithm AlgorithmIdentifier, - signatureValue BIT STRING } + CertificateList ::= SEQUENCE { + tbsCertList TBSCertList, + signatureAlgorithm AlgorithmIdentifier, + signatureValue BIT STRING } - TBSCertList ::= SEQUENCE { - version Version OPTIONAL, - -- if present, shall be v2 - signature AlgorithmIdentifier, - issuer Name, - thisUpdate Time, - nextUpdate Time OPTIONAL, - revokedCertificates SEQUENCE OF SEQUENCE { - userCertificate CertificateSerialNumber, - revocationDate Time, - crlEntryExtensions Extensions OPTIONAL - -- if present, shall be v2 - } OPTIONAL, - crlExtensions [0] EXPLICIT Extensions OPTIONAL - -- if present, shall be v2 - } - */ + TBSCertList ::= SEQUENCE { + version Version OPTIONAL, + -- if present, shall be v2 + signature AlgorithmIdentifier, + issuer Name, + thisUpdate Time, + nextUpdate Time OPTIONAL, + revokedCertificates SEQUENCE OF SEQUENCE { + userCertificate CertificateSerialNumber, + revocationDate Time, + crlEntryExtensions Extensions OPTIONAL + -- if present, shall be v2 + } OPTIONAL, + crlExtensions [0] EXPLICIT Extensions OPTIONAL + -- if present, shall be v2 + } + */ if (getAsnSequence32(&p, (uint32) (end - p), &glen, 0) < 0) { - psTraceCrypto("Initial parse error in psX509ParseCRL\n"); - return PS_PARSE_FAIL; + psTraceCrypto("Initial parse error in psX509ParseCRL\n"); + return PS_PARSE_FAIL; } /* Track tbsCert for signature purposes and for encoding where there - is no revokedCertificate entry */ + is no revokedCertificate entry */ sigStart = p; if (getAsnSequence32(&p, (uint32) (end - p), &tbsCertLen, 0) < 0) { - psTraceCrypto("Initial parse error in psX509ParseCRL\n"); - return PS_PARSE_FAIL; + psTraceCrypto("Initial parse error in psX509ParseCRL\n"); + return PS_PARSE_FAIL; } start = p; if (end > p && *p == ASN_INTEGER) { - version = 0; - if (getAsnInteger(&p, (uint32) (end - p), &version) < 0 || version < 0) - { - psTraceCrypto("Version parse error in psX509ParseCRL.\n"); - return PS_PARSE_FAIL; - } - if (version != 1) - { - psTraceIntCrypto("Version parse: unsupported version requested: " - "%d\n", version); - return PS_VERSION_UNSUPPORTED; - } + version = 0; + if (getAsnInteger(&p, (uint32) (end - p), &version) < 0 || version < 0) + { + psTraceCrypto("Version parse error in psX509ParseCRL.\n"); + return PS_PARSE_FAIL; + } + if (version != 1) + { + psTraceIntCrypto("Version parse: unsupported version requested: " + "%d\n", version); + return PS_VERSION_UNSUPPORTED; + } } /* looking correct. Allocate the psX509Crl_t */ if ((lcrl = psX509AllocCRL(pool)) == NULL) { - return PS_MEM_FAIL; + return PS_MEM_FAIL; } /* signature */ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &lcrl->sigAlg, &plen) - < 0) + < 0) { - psTraceCrypto("Couldn't parse crl sig algorithm identifier\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; + psTraceCrypto("Couldn't parse crl sig algorithm identifier\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; } /* - Name ::= CHOICE { -- only one possibility for now -- - rdnSequence RDNSequence } + Name ::= CHOICE { -- only one possibility for now -- + rdnSequence RDNSequence } - RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - DistinguishedName ::= RDNSequence + DistinguishedName ::= RDNSequence - RelativeDistinguishedName ::= - SET SIZE (1 .. MAX) OF AttributeTypeAndValue - */ + RelativeDistinguishedName ::= + SET SIZE (1 .. MAX) OF AttributeTypeAndValue + */ if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p), - &lcrl->issuer, 0)) < 0) + &lcrl->issuer, 0)) < 0) { - psX509FreeCRL(lcrl); - psTraceCrypto("Couldn't parse crl issuer DN attributes\n"); - return rc; + psX509FreeCRL(lcrl); + psTraceCrypto("Couldn't parse crl issuer DN attributes\n"); + return rc; } /* thisUpdate TIME */ if ((end - p) < 1 || ((*p != ASN_UTCTIME) && (*p != ASN_GENERALIZEDTIME))) { - psTraceCrypto("Malformed thisUpdate CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; + psTraceCrypto("Malformed thisUpdate CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; } timetag = *p; p++; if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 || - (uint32) (end - p) < timelen) + (uint32) (end - p) < timelen) { - psTraceCrypto("Malformed thisUpdate CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; + psTraceCrypto("Malformed thisUpdate CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; } if (psBrokenDownTimeImport( - &lcrl->thisUpdateBDT, (const char *) p, timelen, - timetag == ASN_UTCTIME ? - PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != PS_SUCCESS) + &lcrl->thisUpdateBDT, (const char *) p, timelen, + timetag == ASN_UTCTIME ? + PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != PS_SUCCESS) { - psTraceCrypto("Malformed thisUpdate CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; + psTraceCrypto("Malformed thisUpdate CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; } p += timelen; /* Move p beyond thisUpdate TIME. */ @@ -1006,188 +1006,188 @@ int32 psX509ParseCRL(psPool_t *pool, psX509Crl_t **crl, unsigned char *crlBin, /* nextUpdateTIME - Optional... but required by spec */ if ((end - p) < 1 || ((*p == ASN_UTCTIME) || (*p == ASN_GENERALIZEDTIME))) { - lcrl->nextUpdateType = timetag = *p; - p++; - if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 || - (uint32) (end - p) < timelen) - { - psTraceCrypto("Malformed nextUpdateTIME CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - if ((lcrl->nextUpdate = psMalloc(pool, timelen + 1)) == NULL) - { - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - Memcpy(lcrl->nextUpdate, p, timelen); - lcrl->nextUpdate[timelen] = '\0'; + lcrl->nextUpdateType = timetag = *p; + p++; + if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 || + (uint32) (end - p) < timelen) + { + psTraceCrypto("Malformed nextUpdateTIME CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + if ((lcrl->nextUpdate = psMalloc(pool, timelen + 1)) == NULL) + { + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + Memcpy(lcrl->nextUpdate, p, timelen); + lcrl->nextUpdate[timelen] = '\0'; - if (psBrokenDownTimeImport( - &lcrl->nextUpdateBDT, (const char *) p, timelen, - timetag == ASN_UTCTIME ? - PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != PS_SUCCESS) - { - psTraceCrypto("Malformed thisUpdate CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - p += timelen; + if (psBrokenDownTimeImport( + &lcrl->nextUpdateBDT, (const char *) p, timelen, + timetag == ASN_UTCTIME ? + PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != PS_SUCCESS) + { + psTraceCrypto("Malformed thisUpdate CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + p += timelen; - /* Note: nextUpdate may be in past, but parsing does not - check that. */ + /* Note: nextUpdate may be in past, but parsing does not + check that. */ } else { - Memset(&lcrl->nextUpdateBDT, 0, sizeof(lcrl->nextUpdateBDT)); + Memset(&lcrl->nextUpdateBDT, 0, sizeof(lcrl->nextUpdateBDT)); } /* Need to see if any data left in tbsCertList. Could be no revocations */ if ((p - start) != tbsCertLen) { - /* - revokedCertificates SEQUENCE OF SEQUENCE { - userCertificate CertificateSerialNumber, - revocationDate Time, - crlEntryExtensions Extensions OPTIONAL - -- if present, shall be v2 - } OPTIONAL, - */ + /* + revokedCertificates SEQUENCE OF SEQUENCE { + userCertificate CertificateSerialNumber, + revocationDate Time, + crlEntryExtensions Extensions OPTIONAL + -- if present, shall be v2 + } OPTIONAL, + */ - /* Need to peek at next byte to make sure there are some revoked - certs here. Could be jumping right to crlExtensions */ - if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) - { + /* Need to peek at next byte to make sure there are some revoked + certs here. Could be jumping right to crlExtensions */ + if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) + { - if (getAsnSequence32(&p, (uint32) (end - p), &glen, 0) < 0) - { - psTraceCrypto("Initial revokedCert error in psX509ParseCRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } + if (getAsnSequence32(&p, (uint32) (end - p), &glen, 0) < 0) + { + psTraceCrypto("Initial revokedCert error in psX509ParseCRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } - lcrl->revoked = curr = psMalloc(pool, sizeof(x509revoked_t)); - if (curr == NULL) - { - psX509FreeCRL(lcrl); - return PS_MEM_FAIL; - } - Memset(curr, 0x0, sizeof(x509revoked_t)); - while (glen > 0) - { - revStart = p; - if (getAsnSequence32(&p, (uint32) (end - p), &ilen, 0) < 0) - { - psTraceCrypto("Deep revokedCert error in psX509ParseCRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - start = p; /* reusing start */ - if ((rc = getSerialNum(pool, &p, ilen, &curr->serial, - &curr->serialLen)) < 0) - { - psTraceCrypto("ASN serial number parse error\n"); - psX509FreeCRL(lcrl); - return rc; - } + lcrl->revoked = curr = psMalloc(pool, sizeof(x509revoked_t)); + if (curr == NULL) + { + psX509FreeCRL(lcrl); + return PS_MEM_FAIL; + } + Memset(curr, 0x0, sizeof(x509revoked_t)); + while (glen > 0) + { + revStart = p; + if (getAsnSequence32(&p, (uint32) (end - p), &ilen, 0) < 0) + { + psTraceCrypto("Deep revokedCert error in psX509ParseCRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + start = p; /* reusing start */ + if ((rc = getSerialNum(pool, &p, ilen, &curr->serial, + &curr->serialLen)) < 0) + { + psTraceCrypto("ASN serial number parse error\n"); + psX509FreeCRL(lcrl); + return rc; + } - /* revocationDate */ - if ((end - p) < 1 || ((*p != ASN_UTCTIME) && - (*p != ASN_GENERALIZEDTIME))) - { - psTraceCrypto("Malformed revocationDate CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - timetag = *p; - p++; - if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 || - (uint32) (end - p) < timelen) - { - psTraceCrypto("Malformed thisUpdate CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - if (psBrokenDownTimeImport( - &curr->revocationDateBDT, (const char *) p, - timelen, - timetag == ASN_UTCTIME ? - PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != - PS_SUCCESS) - { - psTraceCrypto("Malformed thisUpdate CRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } + /* revocationDate */ + if ((end - p) < 1 || ((*p != ASN_UTCTIME) && + (*p != ASN_GENERALIZEDTIME))) + { + psTraceCrypto("Malformed revocationDate CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + timetag = *p; + p++; + if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 || + (uint32) (end - p) < timelen) + { + psTraceCrypto("Malformed thisUpdate CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + if (psBrokenDownTimeImport( + &curr->revocationDateBDT, (const char *) p, + timelen, + timetag == ASN_UTCTIME ? + PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != + PS_SUCCESS) + { + psTraceCrypto("Malformed thisUpdate CRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } - /* skipping crlEntryExtensions */ - p += ilen - (uint32) (p - start); - if (glen < (uint32) (p - revStart)) - { - psTraceCrypto("Deeper revokedCert err in psX509ParseCRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - glen -= (uint32) (p - revStart); + /* skipping crlEntryExtensions */ + p += ilen - (uint32) (p - start); + if (glen < (uint32) (p - revStart)) + { + psTraceCrypto("Deeper revokedCert err in psX509ParseCRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + glen -= (uint32) (p - revStart); - /* psTraceBytes("revoked", curr->serial, curr->serialLen); */ - if (glen > 0) - { - if ((next = psMalloc(pool, sizeof(x509revoked_t))) == NULL) - { - psX509FreeCRL(lcrl); - return PS_MEM_FAIL; - } - Memset(next, 0x0, sizeof(x509revoked_t)); - curr->next = next; - curr = next; - } - } - } - /* Always treated as OPTIONAL */ - if (getExplicitExtensions(pool, &p, (uint32) (end - p), 0, - &lcrl->extensions, 0) < 0) - { - psTraceCrypto("Extension parse error in psX509ParseCRL\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; - } - /* if (lcrl->extensions.ak.keyId) { */ - /* psTraceBytes("CRL ak", lcrl->extensions.ak.keyId, 20); */ - /* } */ + /* psTraceBytes("revoked", curr->serial, curr->serialLen); */ + if (glen > 0) + { + if ((next = psMalloc(pool, sizeof(x509revoked_t))) == NULL) + { + psX509FreeCRL(lcrl); + return PS_MEM_FAIL; + } + Memset(next, 0x0, sizeof(x509revoked_t)); + curr->next = next; + curr = next; + } + } + } + /* Always treated as OPTIONAL */ + if (getExplicitExtensions(pool, &p, (uint32) (end - p), 0, + &lcrl->extensions, 0) < 0) + { + psTraceCrypto("Extension parse error in psX509ParseCRL\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; + } + /* if (lcrl->extensions.ak.keyId) { */ + /* psTraceBytes("CRL ak", lcrl->extensions.ak.keyId, 20); */ + /* } */ } /* End tbsCertList */ sigEnd = p; if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen) < 0) { - psX509FreeCRL(lcrl); - psTraceCrypto("Couldn't parse crl sig algorithm identifier\n"); - return PS_PARSE_FAIL; + psX509FreeCRL(lcrl); + psTraceCrypto("Couldn't parse crl sig algorithm identifier\n"); + return PS_PARSE_FAIL; } /* must match */ if (oi != lcrl->sigAlg) { - psTraceCrypto("Couldn't match crl sig algorithm identifier\n"); - psX509FreeCRL(lcrl); - return PS_PARSE_FAIL; + psTraceCrypto("Couldn't match crl sig algorithm identifier\n"); + psX509FreeCRL(lcrl); + return PS_PARSE_FAIL; } if ((rc = psX509GetSignature(pool, &p, (uint32) (end - p), &lcrl->sig, - &lcrl->sigLen)) < 0) + &lcrl->sigLen)) < 0) { - psX509FreeCRL(lcrl); - psTraceCrypto("Couldn't parse signature\n"); - return rc; + psX509FreeCRL(lcrl); + psTraceCrypto("Couldn't parse signature\n"); + return rc; } /* Perform the hashing for later auth */ rc = psComputeHashForSig(sigStart, sigEnd - sigStart, - lcrl->sigAlg, - lcrl->sigHash, &lcrl->sigHashLen); + lcrl->sigAlg, + lcrl->sigHash, &lcrl->sigHashLen); if (rc != PS_SUCCESS) { - psX509FreeCRL(lcrl); - return rc; + psX509FreeCRL(lcrl); + return rc; } *crl = lcrl; @@ -1196,9 +1196,9 @@ int32 psX509ParseCRL(psPool_t *pool, psX509Crl_t **crl, unsigned char *crlBin, } /* - If the provided cert has a URL based CRL Distribution point, return - that. The url and urlLen point directly into the cert structure so - must not be modified. + If the provided cert has a URL based CRL Distribution point, return + that. The url and urlLen point directly into the cert structure so + must not be modified. */ int32 psX509GetCRLdistURL(psX509Cert_t *cert, char **url, uint32_t *urlLen) { @@ -1206,29 +1206,29 @@ int32 psX509GetCRLdistURL(psX509Cert_t *cert, char **url, uint32_t *urlLen) if (cert == NULL) { - return PS_ARG_FAIL; + return PS_ARG_FAIL; } *url = NULL; *urlLen = 0; if (cert->extensions.crlDist != NULL) { - gn = cert->extensions.crlDist; - while (gn) - { - if (gn->id == 6) /* Only pass on URI types */ - { - *url = (char *) gn->data; - *urlLen = gn->dataLen; - return PS_TRUE; - } - else - { - psTraceIntCrypto("Unsupported CRL distro point format %d\n", - gn->id); - } - gn = gn->next; - } + gn = cert->extensions.crlDist; + while (gn) + { + if (gn->id == 6) /* Only pass on URI types */ + { + *url = (char *) gn->data; + *urlLen = gn->dataLen; + return PS_TRUE; + } + else + { + psTraceIntCrypto("Unsupported CRL distro point format %d\n", + gn->id); + } + gn = gn->next; + } } return PS_FALSE; } diff --git a/crypto/keyformat/pem_decode_mem.c b/crypto/keyformat/pem_decode_mem.c index 0ccb79d..ed07c49 100644 --- a/crypto/keyformat/pem_decode_mem.c +++ b/crypto/keyformat/pem_decode_mem.c @@ -357,7 +357,6 @@ psRes_t psPemCertBufToList(psPool_t *pool, else { psFreeList(front, pool); - psTraceCrypto("File buffer does not look to be X.509 PEM format\n"); return PS_PARSE_FAIL; } current->item = psMalloc(pool, current->len); diff --git a/crypto/keyformat/pkcs.c b/crypto/keyformat/pkcs.c index eac741f..fc98105 100644 --- a/crypto/keyformat/pkcs.c +++ b/crypto/keyformat/pkcs.c @@ -747,6 +747,12 @@ static int32 parseSafeContents(psPool_t *pool, unsigned char *password, if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0) { psTraceCrypto("Initial SafeContents parse failure\n"); + if (rc == PS_PARSE_FAIL) + { + /* The error is probably due to decryption error. + Issue the error as PS_AUTH_FAIL. */ + rc = PS_AUTH_FAIL; + } return rc; } @@ -1059,6 +1065,13 @@ static int32 psParseAuthenticatedSafe(psPool_t *pool, psX509Cert_t **cert, privKey, (unsigned char *) p, tmplen)) < 0) { psTraceCrypto("Error parsing plaintext safe contents\n"); + /* parseSafeContents() guesses error code according to + the contents of the safe. If is guessed PS_AUTH_FAIL, + it meant PS_PARSE_FAIL, for plaintext store. */ + if (rc == PS_AUTH_FAIL) + { + rc = PS_PARSE_FAIL; + } return rc; } p += rc; @@ -1165,6 +1178,12 @@ int32 psPkcs12ParseMem(psPool_t *pool, psX509Cert_t **cert, psPubKey_t *privKey, ipass is import password mpass is MAC password */ ipassLen = (pLen * 2) + 2; /* 2 for each char put double 0x0 to terminate */ + if (ipassLen > sizeof iwidePass) + { + psTraceCrypto("Password too long.\n"); + rc = PS_AUTH_FAIL; + goto ERR_PARSE; + } Memset(iwidePass, 0x0, ipassLen); for (i = 1, j = 0; i < ipassLen - 1; i += 2, j++) { @@ -1185,6 +1204,12 @@ int32 psPkcs12ParseMem(psPool_t *pool, psX509Cert_t **cert, psPubKey_t *privKey, if (integrity == PASSWORD_INTEGRITY) { mpassLen = (macPassLen * 2) + 2; + if (mpassLen > sizeof mwidePass) + { + psTraceCrypto("Password too long.\n"); + rc = PS_AUTH_FAIL; + goto ERR_PARSE; + } Memset(mwidePass, 0x0, mpassLen); for (i = 1, j = 0; i < mpassLen - 1; i += 2, j++) { @@ -1276,6 +1301,8 @@ int32 psPkcs12ParseMem(psPool_t *pool, psX509Cert_t **cert, psPubKey_t *privKey, if (Memcmp(digest, mac, SHA1_HASH_SIZE) != 0) { psTraceCrypto("CAUTION: PKCS#12 MAC did not validate\n"); + rc = PS_AUTH_FAIL; + goto ERR_PARSE; } } else @@ -1334,28 +1361,28 @@ int32_t psPkcs5Pbkdf1(unsigned char *pass, uint32 passlen, unsigned char *salt, psAssert(iter == 1); - rc = psMd5Init(&md.md5); + rc = psMd5Init(&md.u.md5); if (rc != PS_SUCCESS) { psTraceCrypto("psMd5Init failed. Please ensure non-FIPS mode.\n"); return rc; } - psMd5Update(&md.md5, pass, passlen); - psMd5Update(&md.md5, salt, 8); - psMd5Final(&md.md5, md5); + psMd5Update(&md.u.md5, pass, passlen); + psMd5Update(&md.u.md5, salt, 8); + psMd5Final(&md.u.md5, md5); Memcpy(key, md5, MD5_HASH_SIZE); - rc = psMd5Init(&md.md5); + rc = psMd5Init(&md.u.md5); if (rc != PS_SUCCESS) { psTraceCrypto("psMd5Init failed. Please ensure non-FIPS mode.\n"); return rc; } - psMd5Update(&md.md5, md5, MD5_HASH_SIZE); - psMd5Update(&md.md5, pass, passlen); - psMd5Update(&md.md5, salt, 8); - psMd5Final(&md.md5, md5); + psMd5Update(&md.u.md5, md5, MD5_HASH_SIZE); + psMd5Update(&md.u.md5, pass, passlen); + psMd5Update(&md.u.md5, salt, 8); + psMd5Final(&md.u.md5, md5); Memcpy(key + MD5_HASH_SIZE, md5, 24 - MD5_HASH_SIZE); memset_s(md5, MD5_HASH_SIZE, 0x0, MD5_HASH_SIZE); @@ -1547,46 +1574,24 @@ static int32 pkcs_1_mgf1(psPool_t *pool, const unsigned char *seed, uint32 counter; psDigestContext_t md; unsigned char *buf; + int32_t rc; + psResSize_t hLenTmp; if ((seed == NULL) || (mask == NULL)) { return -1; } hLen = 0; -/* - Get hash output size. Index has already been verified by caller so - don't need 'else' error cases - */ - if (hash_idx == PKCS1_SHA1_ID) - { - hLen = SHA1_HASH_SIZE; - } - else if (hash_idx == PKCS1_MD5_ID) - { - hLen = MD5_HASH_SIZE; -# ifdef USE_SHA256 - } - else if (hash_idx == PKCS1_SHA256_ID) - { - hLen = SHA256_HASH_SIZE; -# endif -# ifdef USE_SHA384 - } - else if (hash_idx == PKCS1_SHA384_ID) - { - hLen = SHA384_HASH_SIZE; -# endif -# ifdef USE_SHA512 - } - else if (hash_idx == PKCS1_SHA512_ID) - { - hLen = SHA512_HASH_SIZE; -# endif - } - else + + /* Get hash output size. */ + hLenTmp = psPssHashAlgToHashLen(hash_idx); + if (hLenTmp < 0) { + psTraceIntCrypto("Unsupported MGF hash alg: %d\n", + hash_idx); return PS_UNSUPPORTED_FAIL; } + hLen = hLenTmp; buf = psMalloc(pool, hLen); if (buf == NULL) @@ -1608,48 +1613,52 @@ static int32 pkcs_1_mgf1(psPool_t *pool, const unsigned char *seed, /* Get hash of seed || counter */ - if (hash_idx == PKCS1_SHA1_ID) + switch (hash_idx) { - psSha1Init(&md.sha1); - psSha1Update(&md.sha1, seed, seedlen); - psSha1Update(&md.sha1, buf, 4); - psSha1Final(&md.sha1, buf); +# ifdef USE_SHA1 + case PKCS1_SHA1_ID: + psSha1Init(&md.u.sha1); + psSha1Update(&md.u.sha1, seed, seedlen); + psSha1Update(&md.u.sha1, buf, 4); + psSha1Final(&md.u.sha1, buf); + break; +# endif # ifdef USE_MD5 - } - else if (hash_idx == PKCS1_MD5_ID) - { - psMd5Init(&md.md5); - psMd5Update(&md.md5, seed, seedlen); - psMd5Update(&md.md5, buf, 4); - psMd5Final(&md.md5, buf); + case PKCS1_MD5_ID: + psMd5Init(&md.u.md5); + psMd5Update(&md.u.md5, seed, seedlen); + psMd5Update(&md.u.md5, buf, 4); + psMd5Final(&md.u.md5, buf); + break; # endif /* USE_MD5 */ # ifdef USE_SHA256 - } - else if (hash_idx == PKCS1_SHA256_ID) - { - psSha256Init(&md.sha256); - psSha256Update(&md.sha256, seed, seedlen); - psSha256Update(&md.sha256, buf, 4); - psSha256Final(&md.sha256, buf); + case PKCS1_SHA256_ID: + psSha256Init(&md.u.sha256); + psSha256Update(&md.u.sha256, seed, seedlen); + psSha256Update(&md.u.sha256, buf, 4); + psSha256Final(&md.u.sha256, buf); + break; # endif # ifdef USE_SHA384 - } - else if (hash_idx == PKCS1_SHA384_ID) - { - psSha384Init(&md.sha384); - psSha384Update(&md.sha384, seed, seedlen); - psSha384Update(&md.sha384, buf, 4); - psSha384Final(&md.sha384, buf); + case PKCS1_SHA384_ID: + psSha384Init(&md.u.sha384); + psSha384Update(&md.u.sha384, seed, seedlen); + psSha384Update(&md.u.sha384, buf, 4); + psSha384Final(&md.u.sha384, buf); + break; # endif # ifdef USE_SHA512 - } - else if (hash_idx == PKCS1_SHA512_ID) - { - psSha512Init(&md.sha512); - psSha512Update(&md.sha512, seed, seedlen); - psSha512Update(&md.sha512, buf, 4); - psSha512Final(&md.sha512, buf); + case PKCS1_SHA512_ID: + psSha512Init(&md.u.sha512); + psSha512Update(&md.u.sha512, seed, seedlen); + psSha512Update(&md.u.sha512, buf, 4); + psSha512Final(&md.u.sha512, buf); + break; # endif + default: + psTraceCrypto("Unknown PSS MFG hash function\n"); + rc = PS_UNSUPPORTED_FAIL; + goto out_fail; } /* store it */ @@ -1659,8 +1668,11 @@ static int32 pkcs_1_mgf1(psPool_t *pool, const unsigned char *seed, } } + rc = PS_SUCCESS; + +out_fail: psFree(buf, pool); - return PS_SUCCESS; + return rc; } #endif /* defined(USE_PKCS1_OAEP) || defined(USE_PKCS1_PSS) */ @@ -1772,16 +1784,16 @@ int32 psPkcs1OaepEncode(psPool_t *pool, const unsigned char *msg, uint32 msglen, { if (hash_idx == PKCS1_SHA1_ID) { - psSha1Init(&md.sha1); - psSha1Update(&md.sha1, lparam, lparamlen); - psSha1Final(&md.sha1, DB); + psSha1Init(&md.u.sha1); + psSha1Update(&md.u.sha1, lparam, lparamlen); + psSha1Final(&md.u.sha1, DB); } # ifdef USE_MD5 else { - psMd5Init(&md.md5); - psMd5Update(&md.md5, lparam, lparamlen); - psMd5Final(&md.md5, DB); + psMd5Init(&md.u.md5); + psMd5Update(&md.u.md5, lparam, lparamlen); + psMd5Final(&md.u.md5, DB); } # endif /* USE_MD5 */ } @@ -1790,16 +1802,16 @@ int32 psPkcs1OaepEncode(psPool_t *pool, const unsigned char *msg, uint32 msglen, /* can't pass hash a NULL so use DB with zero length */ if (hash_idx == PKCS1_SHA1_ID) { - psSha1Init(&md.sha1); - psSha1Update(&md.sha1, DB, 0); - psSha1Final(&md.sha1, DB); + psSha1Init(&md.u.sha1); + psSha1Update(&md.u.sha1, DB, 0); + psSha1Final(&md.u.sha1, DB); } # ifdef USE_MD5 else { - psMd5Init(&md.md5); - psMd5Update(&md.md5, DB, 0); - psMd5Final(&md.md5, DB); + psMd5Init(&md.u.md5); + psMd5Update(&md.u.md5, DB, 0); + psMd5Final(&md.u.md5, DB); } # endif /* USE_MD5 */ } @@ -2076,16 +2088,16 @@ int32 psPkcs1OaepDecode(psPool_t *pool, const unsigned char *msg, uint32 msglen, { if (hash_idx == PKCS1_SHA1_ID) { - psSha1Init(&md.sha1); - psSha1Update(&md.sha1, lparam, lparamlen); - psSha1Final(&md.sha1, seed); + psSha1Init(&md.u.sha1); + psSha1Update(&md.u.sha1, lparam, lparamlen); + psSha1Final(&md.u.sha1, seed); } # ifdef USE_MD5 else { - psMd5Init(&md.md5); - psMd5Update(&md.md5, lparam, lparamlen); - psMd5Final(&md.md5, seed); + psMd5Init(&md.u.md5); + psMd5Update(&md.u.md5, lparam, lparamlen); + psMd5Final(&md.u.md5, seed); } # endif /* USE_MD5 */ } @@ -2094,16 +2106,16 @@ int32 psPkcs1OaepDecode(psPool_t *pool, const unsigned char *msg, uint32 msglen, /* can't pass hash routine a NULL so use DB with zero length */ if (hash_idx == PKCS1_SHA1_ID) { - psSha1Init(&md.sha1); - psSha1Update(&md.sha1, DB, 0); - psSha1Final(&md.sha1, seed); + psSha1Init(&md.u.sha1); + psSha1Update(&md.u.sha1, DB, 0); + psSha1Final(&md.u.sha1, seed); } # ifdef USE_MD5 else { - psMd5Init(&md.md5); - psMd5Update(&md.md5, DB, 0); - psMd5Final(&md.md5, seed); + psMd5Init(&md.u.md5); + psMd5Update(&md.u.md5, DB, 0); + psMd5Final(&md.u.md5, seed); } # endif /* USE_MD5 */ } @@ -2190,6 +2202,7 @@ int32 psPkcs1PssEncode(psPool_t *pool, const unsigned char *msghash, uint32 x, y, hLen, modulus_len; int32 err; psDigestContext_t md; + psResSize_t hLenTmp; if ((msghash == NULL) || (out == NULL) || (outlen == NULL)) { @@ -2197,43 +2210,15 @@ int32 psPkcs1PssEncode(psPool_t *pool, const unsigned char *msghash, return PS_ARG_FAIL; } - if (hash_idx == PKCS1_SHA1_ID) + /* Get hash output size. */ + hLenTmp = psPssHashAlgToHashLen(hash_idx); + if (hLenTmp < 0) { - hLen = SHA1_HASH_SIZE; - } - else if (hash_idx == PKCS1_MD5_ID) - { -# ifdef USE_MD5 - hLen = MD5_HASH_SIZE; -# else - psTraceCrypto("MD5 not supported in this build."); - psTraceCrypto(" Please enable USE_MD5\n"); + psTraceIntCrypto("Unsupported MGF hash alg: %d\n", + hash_idx); return PS_UNSUPPORTED_FAIL; -# endif /* USE_MD5 */ - } -# ifdef USE_SHA256 - else if (hash_idx == PKCS1_SHA256_ID) - { - hLen = SHA256_HASH_SIZE; - } -# endif -# ifdef USE_SHA384 - else if (hash_idx == PKCS1_SHA384_ID) - { - hLen = SHA384_HASH_SIZE; - } -# endif -# ifdef USE_SHA512 - else if (hash_idx == PKCS1_SHA512_ID) - { - hLen = SHA512_HASH_SIZE; - } -# endif - else - { - psTraceStrCrypto("Bad hash index to PSS encode\n", NULL); - return PS_ARG_FAIL; } + hLen = hLenTmp; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); @@ -2285,54 +2270,58 @@ int32 psPkcs1PssEncode(psPool_t *pool, const unsigned char *msghash, } /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ - if (hash_idx == PKCS1_SHA1_ID) + switch (hash_idx) { - psSha1Init(&md.sha1); - psSha1Update(&md.sha1, DB, 8); /* 8 0's */ - psSha1Update(&md.sha1, msghash, msghashlen); - psSha1Update(&md.sha1, salt, saltlen); - psSha1Final(&md.sha1, hash); - } +# ifdef USE_SHA1 + case PKCS1_SHA1_ID: + psSha1Init(&md.u.sha1); + psSha1Update(&md.u.sha1, DB, 8); /* 8 0's */ + psSha1Update(&md.u.sha1, msghash, msghashlen); + psSha1Update(&md.u.sha1, salt, saltlen); + psSha1Final(&md.u.sha1, hash); + break; +# endif # ifdef USE_MD5 - if (hash_idx == PKCS1_MD5_ID) - { - psMd5Init(&md.md5); - psMd5Update(&md.md5, DB, 8); /* 8 0's */ - psMd5Update(&md.md5, msghash, msghashlen); - psMd5Update(&md.md5, salt, saltlen); - psMd5Final(&md.md5, hash); - } + case PKCS1_MD5_ID: + psMd5Init(&md.u.md5); + psMd5Update(&md.u.md5, DB, 8); /* 8 0's */ + psMd5Update(&md.u.md5, msghash, msghashlen); + psMd5Update(&md.u.md5, salt, saltlen); + psMd5Final(&md.u.md5, hash); + break; # endif /* USE_MD5 */ # ifdef USE_SHA256 - if (hash_idx == PKCS1_SHA256_ID) - { - psSha256Init(&md.sha256); - psSha256Update(&md.sha256, DB, 8); /* 8 0's */ - psSha256Update(&md.sha256, msghash, msghashlen); - psSha256Update(&md.sha256, salt, saltlen); - psSha256Final(&md.sha256, hash); - } + case PKCS1_SHA256_ID: + psSha256Init(&md.u.sha256); + psSha256Update(&md.u.sha256, DB, 8); /* 8 0's */ + psSha256Update(&md.u.sha256, msghash, msghashlen); + psSha256Update(&md.u.sha256, salt, saltlen); + psSha256Final(&md.u.sha256, hash); + break; # endif # ifdef USE_SHA384 - if (hash_idx == PKCS1_SHA384_ID) - { - psSha384Init(&md.sha384); - psSha384Update(&md.sha384, DB, 8); /* 8 0's */ - psSha384Update(&md.sha384, msghash, msghashlen); - psSha384Update(&md.sha384, salt, saltlen); - psSha384Final(&md.sha384, hash); - } + case PKCS1_SHA384_ID: + psSha384Init(&md.u.sha384); + psSha384Update(&md.u.sha384, DB, 8); /* 8 0's */ + psSha384Update(&md.u.sha384, msghash, msghashlen); + psSha384Update(&md.u.sha384, salt, saltlen); + psSha384Final(&md.u.sha384, hash); + break; # endif # ifdef USE_SHA512 - if (hash_idx == PKCS1_SHA512_ID) - { - psSha512Init(&md.sha512); - psSha512Update(&md.sha512, DB, 8); /* 8 0's */ - psSha512Update(&md.sha512, msghash, msghashlen); - psSha512Update(&md.sha512, salt, saltlen); - psSha512Final(&md.sha512, hash); - } + case PKCS1_SHA512_ID: + psSha512Init(&md.u.sha512); + psSha512Update(&md.u.sha512, DB, 8); /* 8 0's */ + psSha512Update(&md.u.sha512, msghash, msghashlen); + psSha512Update(&md.u.sha512, salt, saltlen); + psSha512Final(&md.u.sha512, hash); + break; # endif + default: + psTraceIntCrypto("Unsupported PSS MFG alg: %d\n", hash_idx); + err = PS_UNSUPPORTED_FAIL; + goto LBL_ERR; + } /* generate DB = PS || 0x01 || salt PS == modulus_len - saltlen - hLen - 2 zero bytes */ @@ -2412,6 +2401,7 @@ int32 psPkcs1PssDecode(psPool_t *pool, const unsigned char *msghash, uint32 x, y, hLen, modulus_len; int32 err; psDigestContext_t md; + psResSize_t hLenTmp; if ((msghash == NULL) || (res == NULL)) { @@ -2422,43 +2412,15 @@ int32 psPkcs1PssDecode(psPool_t *pool, const unsigned char *msghash, /* default to invalid */ *res = 0; - if (hash_idx == PKCS1_SHA1_ID) + /* Get hash output size. */ + hLenTmp = psPssHashAlgToHashLen(hash_idx); + if (hLenTmp < 0) { - hLen = SHA1_HASH_SIZE; - } - else if (hash_idx == PKCS1_MD5_ID) - { -# ifdef USE_MD5 - hLen = MD5_HASH_SIZE; -# else - psTraceCrypto("MD5 not supported in this build."); - psTraceCrypto(" Please enable USE_MD5\n"); + psTraceIntCrypto("Unsupported MGF hash alg: %d\n", + hash_idx); return PS_UNSUPPORTED_FAIL; -# endif /* USE_MD5 */ -# ifdef USE_SHA256 - } - else if (hash_idx == PKCS1_SHA256_ID) - { - hLen = SHA256_HASH_SIZE; -# endif -# ifdef USE_SHA384 - } - else if (hash_idx == PKCS1_SHA384_ID) - { - hLen = SHA384_HASH_SIZE; -# endif -# ifdef USE_SHA512 - } - else if (hash_idx == PKCS1_SHA512_ID) - { - hLen = SHA512_HASH_SIZE; -# endif - } - else - { - psTraceStrCrypto("Bad hash index to PSS decode\n", NULL); - return PS_ARG_FAIL; } + hLen = hLenTmp; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); @@ -2553,60 +2515,64 @@ int32 psPkcs1PssDecode(psPool_t *pool, const unsigned char *msghash, } /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ - if (hash_idx == PKCS1_SHA1_ID) + switch (hash_idx) { - psSha1Init(&md.sha1); +# ifdef USE_SHA1 + case PKCS1_SHA1_ID: + psSha1Init(&md.u.sha1); Memset(mask, 0x0, 8); - psSha1Update(&md.sha1, mask, 8); - psSha1Update(&md.sha1, msghash, msghashlen); - psSha1Update(&md.sha1, DB + x, saltlen); - psSha1Final(&md.sha1, mask); - } + psSha1Update(&md.u.sha1, mask, 8); + psSha1Update(&md.u.sha1, msghash, msghashlen); + psSha1Update(&md.u.sha1, DB + x, saltlen); + psSha1Final(&md.u.sha1, mask); + break; +# endif # ifdef USE_MD5 - if (hash_idx == PKCS1_MD5_ID) - { - psMd5Init(&md.md5); + case PKCS1_MD5_ID: + psMd5Init(&md.u.md5); Memset(mask, 0x0, 8); - psMd5Update(&md.md5, mask, 8); - psMd5Update(&md.md5, msghash, msghashlen); - psMd5Update(&md.md5, DB + x, saltlen); - psMd5Final(&md.md5, mask); - } + psMd5Update(&md.u.md5, mask, 8); + psMd5Update(&md.u.md5, msghash, msghashlen); + psMd5Update(&md.u.md5, DB + x, saltlen); + psMd5Final(&md.u.md5, mask); + break; # endif /* USE_MD5 */ - # ifdef USE_SHA256 - if (hash_idx == PKCS1_SHA256_ID) - { - psSha256Init(&md.sha256); + case PKCS1_SHA256_ID: + psSha256Init(&md.u.sha256); Memset(mask, 0x0, 8); - psSha256Update(&md.sha256, mask, 8); - psSha256Update(&md.sha256, msghash, msghashlen); - psSha256Update(&md.sha256, DB + x, saltlen); - psSha256Final(&md.sha256, mask); - } + psSha256Update(&md.u.sha256, mask, 8); + psSha256Update(&md.u.sha256, msghash, msghashlen); + psSha256Update(&md.u.sha256, DB + x, saltlen); + psSha256Final(&md.u.sha256, mask); + break; # endif # ifdef USE_SHA384 - if (hash_idx == PKCS1_SHA384_ID) - { - psSha384Init(&md.sha384); + case PKCS1_SHA384_ID: + psSha384Init(&md.u.sha384); Memset(mask, 0x0, 8); - psSha384Update(&md.sha384, mask, 8); - psSha384Update(&md.sha384, msghash, msghashlen); - psSha384Update(&md.sha384, DB + x, saltlen); - psSha384Final(&md.sha384, mask); - } + psSha384Update(&md.u.sha384, mask, 8); + psSha384Update(&md.u.sha384, msghash, msghashlen); + psSha384Update(&md.u.sha384, DB + x, saltlen); + psSha384Final(&md.u.sha384, mask); + break; # endif # ifdef USE_SHA512 - if (hash_idx == PKCS1_SHA512_ID) - { - psSha512Init(&md.sha512); + case PKCS1_SHA512_ID: + psSha512Init(&md.u.sha512); Memset(mask, 0x0, 8); - psSha512Update(&md.sha512, mask, 8); - psSha512Update(&md.sha512, msghash, msghashlen); - psSha512Update(&md.sha512, DB + x, saltlen); - psSha512Final(&md.sha512, mask); - } + psSha512Update(&md.u.sha512, mask, 8); + psSha512Update(&md.u.sha512, msghash, msghashlen); + psSha512Update(&md.u.sha512, DB + x, saltlen); + psSha512Final(&md.u.sha512, mask); + break; # endif + default: + psTraceIntCrypto("Unsupported PSS MFG hash alg: %d\n", + hash_idx); + err = PS_UNSUPPORTED_FAIL; + goto LBL_ERR; + } /* mask == hash means valid signature */ if (Memcmp(mask, hash, hLen) == 0) diff --git a/crypto/keyformat/x509.c b/crypto/keyformat/x509.c index 5832a60..8faa352 100644 --- a/crypto/keyformat/x509.c +++ b/crypto/keyformat/x509.c @@ -96,16 +96,21 @@ typedef enum X509_V1, /* 1988 X.509v1 Pre-RFC */ } rfc_e; +#ifdef PS_FIND_OID_NEEDED # ifdef USE_CRYPTO_TRACE # define OID_LIST(A, B) { { A, B }, #B, oid_ ## B } # else # define OID_LIST(A, B) { { A, B }, oid_ ## B } # endif + +/* Oid database. + Note: This database is used only by deprecated functions. + The current database is found in oid_names and oid_list_e. */ static const struct { uint16_t oid[MAX_OID_LEN]; # ifdef USE_CRYPTO_TRACE - char name[32]; + char name[33]; # endif int id; } oid_list[] = { @@ -146,6 +151,99 @@ static const struct /* List terminator */ OID_LIST(0, 0), }; +#endif /* PS_FIND_OID_NEEDED */ + +#define OID_NAME(A, B) { oid_ ## B, #B } + +static const struct +{ + int id; + const char name[33]; /* 33 is based on the current maximum length. */ +} oid_names[] = { + /* X.509 certificate extensions */ + OID_NAME(id_ce, id_ce_authorityKeyIdentifier), + OID_NAME(id_ce, id_ce_subjectKeyIdentifier), + OID_NAME(id_ce, id_ce_keyUsage), + OID_NAME(id_ce, id_ce_certificatePolicies), + OID_NAME(id_ce, id_ce_policyMappings), + OID_NAME(id_ce, id_ce_subjectAltName), + OID_NAME(id_ce, id_ce_issuerAltName), + OID_NAME(id_ce, id_ce_subjectDirectoryAttributes), + OID_NAME(id_ce, id_ce_basicConstraints), + OID_NAME(id_ce, id_ce_nameConstraints), + OID_NAME(id_ce, id_ce_policyConstraints), + OID_NAME(id_ce, id_ce_extKeyUsage), + OID_NAME(id_ce, id_ce_cRLDistributionPoints), + OID_NAME(id_ce, id_ce_cRLNumber), + OID_NAME(id_ce, id_ce_issuingDistributionPoint), + OID_NAME(id_ce, id_ce_inhibitAnyPolicy), + OID_NAME(id_ce, id_ce_freshestCRL), + OID_NAME(id_pe, id_pe_authorityInfoAccess), + OID_NAME(id_pe, id_pe_subjectInfoAccess), + /* Extended Key Usage */ + OID_NAME(id_ce_eku, id_ce_eku_anyExtendedKeyUsage), + OID_NAME(id_kp, id_kp_serverAuth), + OID_NAME(id_kp, id_kp_clientAuth), + OID_NAME(id_kp, id_kp_codeSigning), + OID_NAME(id_kp, id_kp_emailProtection), + OID_NAME(id_kp, id_kp_timeStamping), + OID_NAME(id_kp, id_kp_OCSPSigning), + /* policyIdentifiers */ + OID_NAME(id_qt, id_qt_cps), + OID_NAME(id_qt, id_qt_unotice), + /* accessDescriptors */ + OID_NAME(id_ad, id_ad_caIssuers), + OID_NAME(id_ad, id_ad_ocsp), + /* List terminator */ + OID_NAME(0, 0), +}; + +#undef OID_NAME + +#define OID_LIST_E(A, B, C, D) { oid_ ## B, D} /* A and C are for only for reader of the source code. */ + +/* Oid for mapping between encoding and id. */ +static const struct +{ + int id; + const char *oid_encoded; +} oid_list_e[] = { + /* X.509 certificate extensions */ + OID_LIST_E(id_ce, id_ce_authorityKeyIdentifier, 2.5.29.35, "\x06\x03\x55\x1D\x23"), + OID_LIST_E(id_ce, id_ce_subjectKeyIdentifier, 2.5.29.14, "\x06\x03\x55\x1D\x0E"), + OID_LIST_E(id_ce, id_ce_keyUsage, 2.5.29.15, "\x06\x03\x55\x1D\x0F"), + OID_LIST_E(id_ce, id_ce_certificatePolicies, 2.5.29.32, "\x06\x03\x55\x1D\x20"), + OID_LIST_E(id_ce, id_ce_policyMappings, 2.5.29.33, "\x06\x03\x55\x1D\x21"), + OID_LIST_E(id_ce, id_ce_subjectAltName, 2.5.29.17, "\x06\x03\x55\x1D\x11"), + OID_LIST_E(id_ce, id_ce_issuerAltName, 2.5.29.18, "\x06\x03\x55\x1D\x12"), + OID_LIST_E(id_ce, id_ce_subjectDirectoryAttributes, 2.5.29.9, "\x06\x03\x55\x1D\x09"), + OID_LIST_E(id_ce, id_ce_basicConstraints, 2.5.29.19, "\x06\x03\x55\x1D\x13"), + OID_LIST_E(id_ce, id_ce_nameConstraints, 2.5.29.30, "\x06\x03\x55\x1D\x1E"), + OID_LIST_E(id_ce, id_ce_policyConstraints, 2.5.29.36, "\x06\x03\x55\x1D\x24"), + OID_LIST_E(id_ce, id_ce_extKeyUsage, 2.5.29.37, "\x06\x03\x55\x1D\x25"), + OID_LIST_E(id_ce, id_ce_cRLDistributionPoints, 2.5.29.31, "\x06\x03\x55\x1D\x1F"), + OID_LIST_E(id_ce, id_ce_cRLNumber, 2.5.29.20, "\x06\x03\x55\x1D\x14"), + OID_LIST_E(id_ce, id_ce_issuingDistributionPoint, 2.5.29.28, "\x06\x03\x55\x1D\x1C"), + OID_LIST_E(id_ce, id_ce_inhibitAnyPolicy, 2.5.29.54, "\x06\x03\x55\x1D\x36"), + OID_LIST_E(id_ce, id_ce_freshestCRL, 2.5.29.46, "\x06\x03\x55\x1D\x2E"), + OID_LIST_E(id_pe, id_pe_authorityInfoAccess, 1.3.6.1.5.5.7.1.1, "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x01"), + OID_LIST_E(id_pe, id_pe_subjectInfoAccess, 1.3.6.1.5.5.7.1.11, "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x0B"), + OID_LIST_E(id_ce_eku, id_ce_eku_anyExtendedKeyUsage, 2.5.29.37.0, "\x06\x04\x55\x1D\x25\x00"), + OID_LIST_E(id_kp, id_kp_serverAuth, 1.3.6.1.5.5.7.3.1, "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x01"), + OID_LIST_E(id_kp, id_kp_clientAuth, 1.3.6.1.5.5.7.3.2, "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x02"), + OID_LIST_E(id_kp, id_kp_codeSigning, 1.3.6.1.5.5.7.3.3, "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x03"), + OID_LIST_E(id_kp, id_kp_emailProtection, 1.3.6.1.5.5.7.3.4, "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x04"), + OID_LIST_E(id_kp, id_kp_timeStamping, 1.3.6.1.5.5.7.3.8, "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x08"), + OID_LIST_E(id_kp, id_kp_OCSPSigning, 1.3.6.1.5.5.7.3.9, "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x09"), + OID_LIST_E(id_qt, id_qt_cps, 1.3.6.1.5.5.7.2.1, "\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01"), + OID_LIST_E(id_qt, id_qt_unotice, 1.3.6.1.5.5.7.2.2, "\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x02"), + OID_LIST_E(id_ad, id_ad_caIssuers, 1.3.6.1.5.5.7.48.2, "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x02"), + OID_LIST_E(id_ad, id_ad_ocsp, 1.3.6.1.5.5.7.48.1, "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x01"), + /* List terminator */ + OID_LIST_E(0, 0, 0, NULL), +}; + +#undef OID_LIST_E /* Hybrid ASN.1/X.509 cert parsing helpers @@ -185,7 +283,16 @@ psRes_t psX509ParseCertData(psPool_t *pool, if (err < PS_SUCCESS) { /* PEM serialization failed or not supported. Try binary input. */ - err = psX509ParseCert(pool, buf, len, certs, flags); + err = psX509ParseCert(pool, buf, len, ¤t, flags); + if (err < 0) + { + psX509FreeCert(current); + } + else + { + *tailp = current; + tailp = &(current->next); + } return err; } @@ -200,8 +307,10 @@ psRes_t psX509ParseCertData(psPool_t *pool, for (certData = certDatas; certData; certData = certData->next) { err = psX509ParseCert(pool, - certData->item, certData->len, - ¤t, flags); + certData->item, + certData->len, + ¤t, + flags); if (err < 0 && !(flags & CERT_ALLOW_BUNDLE_PARTIAL_PARSE)) { psX509FreeCert(current); @@ -537,6 +646,37 @@ PSPUBLIC int32 psX509GetCertPublicKeyDer(psX509Cert_t *cert, return PS_SUCCESS; } +# ifdef USE_CERT_PARSE +static +psRes_t getCertSignatureHashLen(psX509Cert_t *cert, + psSize_t *sigHashLenOut) +{ + psResSize_t sigHashLen; + +# ifdef USE_PKCS1_PSS + if (cert->certAlgorithm == OID_RSASSA_PSS) + { + sigHashLen = psPssHashAlgToHashLen(cert->pssHash); + } + else +# endif /* USE_PKCS1_PSS */ + { + sigHashLen = psSigAlgToHashLen(cert->sigAlgorithm); + } + + if (sigHashLen < 0) + { + psTraceIntCrypto("Unsupported cert sig hash alg: %d\n", + (int)cert->sigAlgorithm); + return PS_UNSUPPORTED_FAIL; + } + + *sigHashLenOut = (psSize_t)sigHashLen; + + return PS_SUCCESS; +} +# endif /* USE_CERT_PARSE */ + /* Parse a single, DER-encoded ASN.1 Certificate. @@ -631,11 +771,11 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, # ifdef ENABLE_CA_CERT_HASH /* We use the cert_sha1_hash type for the Trusted CA Indication so run a SHA1 has over the entire Certificate DER encoding. */ - psSha1PreInit(&hashCtx.sha1); - psSha1Init(&hashCtx.sha1); - psSha1Update(&hashCtx.sha1, certStart, + psSha1PreInit(&hashCtx.u.sha1); + psSha1Init(&hashCtx.u.sha1); + psSha1Update(&hashCtx.u.sha1, certStart, oneCertLen + (int32) (p - certStart)); - psSha1Final(&hashCtx.sha1, cert->sha1CertHash); + psSha1Final(&hashCtx.u.sha1, cert->sha1CertHash); # endif # ifdef USE_CERT_PARSE @@ -899,6 +1039,7 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, # endif # ifdef USE_RSA case OID_RSA_KEY_ALG: + case OID_RSASSA_PSS: psAssert(plen == 0); /* No parameters on RSA pub key OID */ psInitPubKey(pool, &cert->publicKey, PS_RSA); if ((rc = psRsaParseAsnPubKey(pool, &p, (uint16_t) (end - p), @@ -1071,7 +1212,44 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, goto out; } - cert->sigHashLen = psSigAlgToHashLen(cert->sigAlgorithm); + rc = getCertSignatureHashLen(cert, &cert->sigHashLen); + if (rc < 0) + { + return rc; + } + +# ifdef USE_ROT_CRYPTO + switch (cert->certAlgorithm) + { +# ifdef USE_ROT_ECC + case OID_SHA256_ECDSA_SIG: +# ifdef USE_SECP384R1 + case OID_SHA384_ECDSA_SIG: +# endif +# ifdef USE_SECP521R1 + case OID_SHA512_ECDSA_SIG: +# endif +# endif /* USE_ROT_ECC */ +# ifdef USE_ROT_RSA + case OID_SHA256_RSA_SIG: + case OID_SHA384_RSA_SIG: +# endif /* USE_ROT_RSA */ + /* No pre-hashing used with crypto-rot. */ + (void)hashCtx; + cert->tbsCertStart = psMalloc(pool, certLen); + if (cert->tbsCertStart == NULL) + { + return PS_MEM_FAIL; + } + Memcpy(cert->tbsCertStart, tbsCertStart, certLen); + cert->tbsCertLen = certLen; + goto preprocessing_complete; + break; + default: + psTraceCrypto("Warning: cert sig alg not supported by crypto-rot\n"); + psTraceCrypto("Falling back to SW crypto\n"); + } +# endif /* USE_ROT_CRYPTO */ /* Compute the hash of the cert here for CA validation @@ -1081,22 +1259,22 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, # ifdef ENABLE_MD5_SIGNED_CERTS # ifdef USE_MD2 case OID_MD2_RSA_SIG: - psMd2Init(&hashCtx.md2); - psMd2Update(&hashCtx.md2, tbsCertStart, certLen); - psMd2Final(&hashCtx.md2, cert->sigHash); + psMd2Init(&hashCtx.u.md2); + psMd2Update(&hashCtx.u.md2, tbsCertStart, certLen); + psMd2Final(&hashCtx.u.md2, cert->sigHash); break; # endif /* USE_MD2 */ # ifdef USE_MD4 case OID_MD4_RSA_SIG: - psMd4Init(&hashCtx.md4); - psMd4Update(&hashCtx.md4, tbsCertStart, certLen); - psMd4Final(&hashCtx.md4, cert->sigHash); + psMd4Init(&hashCtx.u.md4); + psMd4Update(&hashCtx.u.md4, tbsCertStart, certLen); + psMd4Final(&hashCtx.u.md4, cert->sigHash); break; # endif /* USE_MD4 */ case OID_MD5_RSA_SIG: - psMd5Init(&hashCtx.md5); - psMd5Update(&hashCtx.md5, tbsCertStart, certLen); - psMd5Final(&hashCtx.md5, cert->sigHash); + psMd5Init(&hashCtx.u.md5); + psMd5Update(&hashCtx.u.md5, tbsCertStart, certLen); + psMd5Final(&hashCtx.u.md5, cert->sigHash); break; # endif # ifdef USE_SHA1 @@ -1117,10 +1295,10 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, goto unsupported_sig_alg; } # endif /* !ENABLE_SHA1_SIGNED_CERTS */ - psSha1PreInit(&hashCtx.sha1); - psSha1Init(&hashCtx.sha1); - psSha1Update(&hashCtx.sha1, tbsCertStart, certLen); - psSha1Final(&hashCtx.sha1, cert->sigHash); + psSha1PreInit(&hashCtx.u.sha1); + psSha1Init(&hashCtx.u.sha1); + psSha1Update(&hashCtx.u.sha1, tbsCertStart, certLen); + psSha1Final(&hashCtx.u.sha1, cert->sigHash); break; # endif /* USE_SHA1 */ # ifdef USE_SHA224 @@ -1128,10 +1306,10 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, # ifdef USE_ECC case OID_SHA224_ECDSA_SIG: # endif - psSha224PreInit(&hashCtx.sha256); - psSha224Init(&hashCtx.sha256); - psSha224Update(&hashCtx.sha256, tbsCertStart, certLen); - psSha224Final(&hashCtx.sha256, cert->sigHash); + psSha224PreInit(&hashCtx.u.sha256); + psSha224Init(&hashCtx.u.sha256); + psSha224Update(&hashCtx.u.sha256, tbsCertStart, certLen); + psSha224Final(&hashCtx.u.sha256, cert->sigHash); break; # endif # ifdef USE_SHA256 @@ -1139,10 +1317,10 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, # ifdef USE_ECC case OID_SHA256_ECDSA_SIG: # endif - psSha256PreInit(&hashCtx.sha256); - psSha256Init(&hashCtx.sha256); - psSha256Update(&hashCtx.sha256, tbsCertStart, certLen); - psSha256Final(&hashCtx.sha256, cert->sigHash); + psSha256PreInit(&hashCtx.u.sha256); + psSha256Init(&hashCtx.u.sha256); + psSha256Update(&hashCtx.u.sha256, tbsCertStart, certLen); + psSha256Final(&hashCtx.u.sha256, cert->sigHash); break; # endif # ifdef USE_SHA384 @@ -1150,10 +1328,10 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, # ifdef USE_ECC case OID_SHA384_ECDSA_SIG: # endif - psSha384PreInit(&hashCtx.sha384); - psSha384Init(&hashCtx.sha384); - psSha384Update(&hashCtx.sha384, tbsCertStart, certLen); - psSha384Final(&hashCtx.sha384, cert->sigHash); + psSha384PreInit(&hashCtx.u.sha384); + psSha384Init(&hashCtx.u.sha384); + psSha384Update(&hashCtx.u.sha384, tbsCertStart, certLen); + psSha384Final(&hashCtx.u.sha384, cert->sigHash); break; # endif # ifdef USE_SHA512 @@ -1161,10 +1339,10 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, # ifdef USE_ECC case OID_SHA512_ECDSA_SIG: # endif - psSha512PreInit(&hashCtx.sha512); - psSha512Init(&hashCtx.sha512); - psSha512Update(&hashCtx.sha512, tbsCertStart, certLen); - psSha512Final(&hashCtx.sha512, cert->sigHash); + psSha512PreInit(&hashCtx.u.sha512); + psSha512Init(&hashCtx.u.sha512); + psSha512Update(&hashCtx.u.sha512, tbsCertStart, certLen); + psSha512Final(&hashCtx.u.sha512, cert->sigHash); break; # endif # ifdef USE_ED25519 @@ -1187,49 +1365,49 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, { # ifdef ENABLE_MD5_SIGNED_CERTS case PKCS1_MD5_ID: - psMd5Init(&hashCtx.md5); - psMd5Update(&hashCtx.md5, tbsCertStart, certLen); - psMd5Final(&hashCtx.md5, cert->sigHash); + psMd5Init(&hashCtx.u.md5); + psMd5Update(&hashCtx.u.md5, tbsCertStart, certLen); + psMd5Final(&hashCtx.u.md5, cert->sigHash); break; # endif # ifdef ENABLE_SHA1_SIGNED_CERTS case PKCS1_SHA1_ID: - psSha1PreInit(&hashCtx.sha1); - psSha1Init(&hashCtx.sha1); - psSha1Update(&hashCtx.sha1, tbsCertStart, certLen); - psSha1Final(&hashCtx.sha1, cert->sigHash); + psSha1PreInit(&hashCtx.u.sha1); + psSha1Init(&hashCtx.u.sha1); + psSha1Update(&hashCtx.u.sha1, tbsCertStart, certLen); + psSha1Final(&hashCtx.u.sha1, cert->sigHash); break; # endif # ifdef USE_SHA224 case PKCS1_SHA224_ID: - psSha224PreInit(&hashCtx.sha256); - psSha224Init(&hashCtx.sha256); - psSha224Update(&hashCtx.sha256, tbsCertStart, certLen); - psSha224Final(&hashCtx.sha256, cert->sigHash); + psSha224PreInit(&hashCtx.u.sha256); + psSha224Init(&hashCtx.u.sha256); + psSha224Update(&hashCtx.u.sha256, tbsCertStart, certLen); + psSha224Final(&hashCtx.u.sha256, cert->sigHash); break; # endif # ifdef USE_SHA256 case PKCS1_SHA256_ID: - psSha256PreInit(&hashCtx.sha256); - psSha256Init(&hashCtx.sha256); - psSha256Update(&hashCtx.sha256, tbsCertStart, certLen); - psSha256Final(&hashCtx.sha256, cert->sigHash); + psSha256PreInit(&hashCtx.u.sha256); + psSha256Init(&hashCtx.u.sha256); + psSha256Update(&hashCtx.u.sha256, tbsCertStart, certLen); + psSha256Final(&hashCtx.u.sha256, cert->sigHash); break; # endif # ifdef USE_SHA384 case PKCS1_SHA384_ID: - psSha384PreInit(&hashCtx.sha384); - psSha384Init(&hashCtx.sha384); - psSha384Update(&hashCtx.sha384, tbsCertStart, certLen); - psSha384Final(&hashCtx.sha384, cert->sigHash); + psSha384PreInit(&hashCtx.u.sha384); + psSha384Init(&hashCtx.u.sha384); + psSha384Update(&hashCtx.u.sha384, tbsCertStart, certLen); + psSha384Final(&hashCtx.u.sha384, cert->sigHash); break; # endif # ifdef USE_SHA512 case PKCS1_SHA512_ID: - psSha512PreInit(&hashCtx.sha512); - psSha512Init(&hashCtx.sha512); - psSha512Update(&hashCtx.sha512, tbsCertStart, certLen); - psSha512Final(&hashCtx.sha512, cert->sigHash); + psSha512PreInit(&hashCtx.u.sha512); + psSha512Init(&hashCtx.u.sha512); + psSha512Update(&hashCtx.u.sha512, tbsCertStart, certLen); + psSha512Final(&hashCtx.u.sha512, cert->sigHash); break; # endif default: @@ -1242,7 +1420,7 @@ static int parse_single_cert(psPool_t *pool, const unsigned char **pp, break; # endif /* USE_PKCS1_PSS */ -# ifndef ENABLE_SHA1_SIGNED_CERTS +# if defined(USE_SHA1) && !defined(ENABLE_SHA1_SIGNED_CERTS) unsupported_sig_alg: # endif default: @@ -1266,6 +1444,9 @@ unsupported_sig_alg: } # endif /* USE_CERT_PARSE */ +# ifdef USE_ROT_CRYPTO +preprocessing_complete: +# endif /* USE_ROT_CRYPTO */ if ((rc = psX509GetSignature(pool, &p, (uint32) (end - p), &cert->signature, &cert->signatureLen)) < 0) { @@ -1475,9 +1656,11 @@ void x509FreeExtensions(x509v3extensions_t *extensions) x509GeneralName_t *active, *inc; # if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN) +# ifdef USE_CERT_POLICY_EXTENSIONS x509PolicyQualifierInfo_t *qual_info, *qual_info_inc; x509PolicyInformation_t *pol_info, *pol_info_inc; x509policyMappings_t *pol_map, *pol_map_inc; +# endif x509authorityInfoAccess_t *authInfo, *authInfoInc; # endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */ @@ -1596,12 +1779,13 @@ void x509FreeExtensions(x509v3extensions_t *extensions) psX509FreeDNStruct(&extensions->ak.attribs, extensions->pool); # if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN) +# ifdef USE_CERT_POLICY_EXTENSIONS pol_info = extensions->certificatePolicy.policy; while (pol_info != NULL) { /* Free PolicyInformation member variables. */ pol_info_inc = pol_info->next; - psFree(pol_info->policyOid, extensions->pool); + psFree(pol_info->policyAsnOid, extensions->pool); qual_info = pol_info->qualifiers; while (qual_info != NULL) { @@ -1626,6 +1810,7 @@ void x509FreeExtensions(x509v3extensions_t *extensions) psFree(pol_map, extensions->pool); pol_map = pol_map_inc; } +# endif /* USE_CERT_POLICY_EXTENSIONS */ if (extensions->netscapeComment) { @@ -2236,6 +2421,18 @@ void psX509FreeCert(psX509Cert_t *cert) psFree(curr->uniqueSubjectId, pool); } +# ifdef USE_ROT_ECC + if (curr->pubKeyAlgorithm == OID_ECDSA_KEY_ALG) + { + psFree(curr->tbsCertStart, pool); + } +# endif +# ifdef USE_ROT_RSA + if (curr->pubKeyAlgorithm == OID_RSA_KEY_ALG) + { + psFree(curr->tbsCertStart, pool); + } +# endif if (curr->publicKey.type != PS_NOKEY) { @@ -2712,12 +2909,17 @@ static int32_t parseGeneralNames(psPool_t *pool, const unsigned char **buf, return PS_SUCCESS; } +/* This functionality is considered obsolete. */ +#ifdef PS_FIND_OID_NEEDED /** Look up an OID in our known oid table. @param[in] oid Array of OID segments to look up in table. @param[in] oidlen Number of segments in 'oid' @return A valid OID enum on success, 0 on failure. */ +static oid_e psFindOid(const uint32_t oid[MAX_OID_LEN], uint8_t oidlen) + PSDEPRECATED_WARN; + static oid_e psFindOid(const uint32_t oid[MAX_OID_LEN], uint8_t oidlen) { int i, j; @@ -2739,6 +2941,39 @@ static oid_e psFindOid(const uint32_t oid[MAX_OID_LEN], uint8_t oidlen) } return (oid_e) 0; } +#endif /* PS_FIND_OID_NEEDED */ + +/** + Look up an OID in our known oid table. + @param[in] oid Copy (or reference) to oid + @return A valid OID enum on success, 0 on failure. + */ +static oid_e psOidToEnum(psAsnOid_t oid) +{ + int i; + uint8_t id; + uint8_t len_encoded; + unsigned int len; + + id = oid[0]; + len_encoded = oid[1]; + len = len_encoded + 2; + + if (id != ASN_OID || len > MAX_OID_BYTES) + { + return (oid_e) 0; + } + + for (i = 0; oid_list_e[i].id != 0; i++) + { + if (oid_list_e[i].oid_encoded[1] == len_encoded && + memcmp(oid, oid_list_e[i].oid_encoded, len) == 0) + { + return (oid_e) oid_list_e[i].id; + } + } + return (oid_e) 0; +} # ifdef USE_CRYPTO_TRACE /** @@ -2746,10 +2981,19 @@ static oid_e psFindOid(const uint32_t oid[MAX_OID_LEN], uint8_t oidlen) @param[in] oid Array of OID segments print. @param[in] oidlen Number of segments in 'oid' @return void + + @note: This function is deprecated in favor of psSprintAsnOid(), + which is similarin function but uses different arguments. */ -static void psTraceOid(uint32_t oid[MAX_OID_LEN], uint8_t oidlen) +static inline void psTraceOid(uint32_t oid[MAX_OID_LEN], uint8_t oidlen) + PSDEPRECATED_WARN; +static inline void psTraceOid(uint32_t oid[MAX_OID_LEN], uint8_t oidlen) { - int i, j, found; + int i; +#ifdef PS_FIND_OID_NEEDED + int j; + int found; +#endif /* PS_FIND_OID_NEEDED */ for (i = 0; i < oidlen; i++) { @@ -2762,6 +3006,7 @@ static void psTraceOid(uint32_t oid[MAX_OID_LEN], uint8_t oidlen) psTraceIntCrypto("%u", oid[i]); } } +#ifdef PS_FIND_OID_NEEDED found = 0; for (j = 0; oid_list[j].oid[0] != 0 && !found; j++) { @@ -2778,18 +3023,79 @@ static void psTraceOid(uint32_t oid[MAX_OID_LEN], uint8_t oidlen) } } } +#endif /* PS_FIND_OID_NEEDED */ psTraceCrypto("\n"); } # else # define psTraceOid(A, B) # endif +/******************************************************************************/ + +/** + Print an OID in dot notation, with it's symbolic name, if found. + @param[in] oid Array of OID segments print. + @param[in] oidlen Number of segments in 'oid' + @param[out] out formatting target buffer + (must be sufficient: MAX_OID_PRINTED_LEN will suffice.) + @return void + */ +const char *psSprintAsnOid( + psAsnOid_t oid, + char out[MAX_OID_PRINTED_LEN]) +{ + int i; + const char *orig_out = out; + uint8_t id; + unsigned int len; + char *mem; + oid_e oe; + + id = oid[0]; + len = oid[1] + 2; + + if (id != ASN_OID || len < 2 || len > MAX_OID_BYTES) + { + strcpy(out, "(Illegal OID)"); + return out; + } + + mem = asnFormatOid( + (psPool_t*) MATRIX_NO_POOL, + (const unsigned char *) oid, + len); + + if (mem == NULL) + { + strcpy(out, "(OID cannot be displayed)"); + } + else + { + strcpy(out, mem); + } + + psFree(mem, (psPool_t*) MATRIX_NO_POOL); + + oe = psOidToEnum(oid); + if (oe != oid_0) + { + for (i = 0; oid_names[i].id != oid_0 && oid_names[i].id != oe; i++) + { + /* Search for oid_list_e entry with the oid. */ + } + out += strlen(out); + sprintf(out, " (%s)", oid_names[i].name); + } + return orig_out; /* Return buffer for convenience. */ +} + /******************************************************************************/ /* X509v3 extensions */ # ifdef USE_FULL_CERT_PARSE +# ifdef USE_CERT_POLICY_EXTENSIONS static int32_t parsePolicyQualifierInfo(psPool_t *pool, const unsigned char *p, @@ -2798,8 +3104,7 @@ int32_t parsePolicyQualifierInfo(psPool_t *pool, x509PolicyQualifierInfo_t *qualInfo, psSize_t *qual_info_len) { - uint32_t oid[MAX_OID_LEN] = { 0 }; - uint8_t oidlen; + psAsnOid_t asnOid; oid_e noid; psSize_t len; const unsigned char *qualifierStart, *qualifierEnd; @@ -2830,13 +3135,13 @@ int32_t parsePolicyQualifierInfo(psPool_t *pool, psTraceCrypto("Malformed extension length\n"); return PS_PARSE_FAIL; } - if ((oidlen = asnParseOid(p, len, oid)) < 1) + if (asnCopyOid(p, len, asnOid) < 1) { psTraceCrypto("Malformed extension OID\n"); return PS_PARSE_FAIL; } /* PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )*/ - noid = psFindOid(oid, oidlen); + noid = psOidToEnum(asnOid); p += len; if (noid == oid_id_qt_cps) { @@ -2990,14 +3295,12 @@ int32_t parsePolicyInformation(psPool_t *pool, x509PolicyInformation_t *polInfo, psSize_t *pol_info_len) { - uint32_t oid[MAX_OID_LEN] = { 0 }; - uint8_t oidlen; + psAsnOid_t asnOid; psSize_t len; const unsigned char *qualifierEnd; const unsigned char *polInfoStart, *polInfoEnd; x509PolicyQualifierInfo_t *qualInfo; psSize_t qualInfoLen; - int i; polInfoStart = p; @@ -3028,29 +3331,20 @@ int32_t parsePolicyInformation(psPool_t *pool, psTraceCrypto("Malformed extension length\n"); return PS_PARSE_FAIL; } - if ((oidlen = asnParseOid(p, len, oid)) < 1) + if (asnCopyOid(p, len, asnOid) < 1) { psTraceCrypto("Malformed extension OID\n"); return PS_PARSE_FAIL; } p += len; - if (oidlen == 0 || oidlen > MAX_OID_LEN) - { - psTraceCrypto("Malformed extension OID\n"); - return PS_PARSE_FAIL; - } /* Store the policy ID. */ - polInfo->policyOid = psMalloc(pool, oidlen * sizeof(uint32_t)); - if (polInfo->policyOid == NULL) + polInfo->policyAsnOid = psMalloc(pool, sizeof(psAsnOid_t)); + if (polInfo->policyAsnOid == NULL) { return PS_MEM_FAIL; } - for (i = 0; i < oidlen; i++) - { - polInfo->policyOid[i] = oid[i]; - } - polInfo->policyOidLen = oidlen; + Memcpy(polInfo->policyAsnOid, asnOid, sizeof(psAsnOid_t)); if ((p >= polInfoEnd) || (*p != (ASN_SEQUENCE | ASN_CONSTRUCTED))) @@ -3214,11 +3508,10 @@ int32_t parsePolicyMappings(psPool_t *pool, x509policyMappings_t *policyMappings, psSize_t *polMappingsLen) { - uint32_t oid[MAX_OID_LEN] = { 0 }; - psSize_t len, oidlen; + psAsnOid_t asnOid; + psSize_t len; const unsigned char *polMappingsStart, *polMappingsEnd; x509policyMappings_t *pol_map; - int i; int num_mappings = 0; /* @@ -3272,23 +3565,20 @@ int32_t parsePolicyMappings(psPool_t *pool, psTraceCrypto("getAsnLength failure in policyMappings parsing\n"); return PS_PARSE_FAIL; } - Memset(oid, 0, sizeof(oid)); - if ((oidlen = asnParseOid(p, len, oid)) < 1) + if (asnCopyOid(p, len, asnOid) < 1) { psTraceCrypto("Malformed extension OID\n"); return PS_PARSE_FAIL; } p += len; - pol_map->issuerDomainPolicy = psMalloc(pool, - oidlen * sizeof(uint32_t)); - Memset(pol_map->issuerDomainPolicy, 0, oidlen * sizeof(uint32_t)); - - for (i = 0; i < oidlen; i++) + pol_map->issuerDomainPolicy = psMalloc(pool, sizeof(psAsnOid_t)); + if (pol_map->issuerDomainPolicy == NULL) { - pol_map->issuerDomainPolicy[i] = oid[i]; + psTraceCrypto("Memory allocation failure.\n"); + return PS_PARSE_FAIL; } - pol_map->issuerDomainPolicyLen = oidlen; + Memcpy(pol_map->issuerDomainPolicy, asnOid, sizeof(psAsnOid_t)); /* Parse subjectDomainPolicy OID. */ if (*p++ != ASN_OID) @@ -3303,23 +3593,20 @@ int32_t parsePolicyMappings(psPool_t *pool, psTraceCrypto("getAsnLength failure in policyMappings parsing\n"); return PS_PARSE_FAIL; } - Memset(oid, 0, sizeof(oid)); - if ((oidlen = asnParseOid(p, len, oid)) < 1) + if (asnCopyOid(p, len, asnOid) < 1) { psTraceCrypto("Malformed extension OID\n"); return PS_PARSE_FAIL; } p += len; - pol_map->subjectDomainPolicy = psMalloc(pool, - oidlen * sizeof(uint32_t)); - Memset(pol_map->subjectDomainPolicy, 0, oidlen * sizeof(uint32_t)); - - for (i = 0; i < oidlen; i++) + pol_map->subjectDomainPolicy = psMalloc(pool, sizeof(psAsnOid_t)); + if (pol_map->issuerDomainPolicy == NULL) { - pol_map->subjectDomainPolicy[i] = oid[i]; + psTraceCrypto("Memory allocation failure.\n"); + return PS_PARSE_FAIL; } - pol_map->subjectDomainPolicyLen = oidlen; + Memcpy(pol_map->subjectDomainPolicy, asnOid, sizeof(psAsnOid_t)); ++num_mappings; } @@ -3332,7 +3619,9 @@ int32_t parsePolicyMappings(psPool_t *pool, return PS_SUCCESS; } +# endif /* USE_CERT_POLICY_EXTENSIONS */ +# ifdef USE_CRL static int32_t parseAuthorityInfoAccess(psPool_t *pool, const unsigned char *p, @@ -3340,10 +3629,10 @@ int32_t parseAuthorityInfoAccess(psPool_t *pool, x509authorityInfoAccess_t **authInfo, psSize_t *authInfoLen) { - psSize_t len, oidlen, adLen; + psSize_t len, adLen; const unsigned char *authInfoStart, *authInfoEnd; x509authorityInfoAccess_t *pAuthInfo; - uint32_t oid[MAX_OID_LEN] = { 0 }; + psAsnOid_t asnOid; oid_e noid; int first_entry = 0; @@ -3434,13 +3723,12 @@ int32_t parseAuthorityInfoAccess(psPool_t *pool, psTraceCrypto("getAsnLength failure in authInfo parsing\n"); return PS_PARSE_FAIL; } - Memset(oid, 0, sizeof(oid)); - if ((oidlen = asnParseOid(p, len, oid)) < 1) + if (asnCopyOid(p, len, asnOid) < 1) { psTraceCrypto("Malformed extension OID\n"); return PS_PARSE_FAIL; } - noid = psFindOid(oid, oidlen); + noid = psOidToEnum(asnOid); p += len; if (noid != oid_id_ad_caIssuers && noid != oid_id_ad_ocsp) @@ -3494,6 +3782,7 @@ int32_t parseAuthorityInfoAccess(psPool_t *pool, return PS_SUCCESS; } +# endif /* USE_CRL */ # endif /* USE_FULL_CERT_PARSE */ int32_t getExplicitExtensions(psPool_t *pool, const unsigned char **pp, @@ -3504,16 +3793,17 @@ int32_t getExplicitExtensions(psPool_t *pool, const unsigned char **pp, const unsigned char *extEnd, *extStart, *save; unsigned char critical; psSize_t len, fullExtLen; - uint32_t oid[MAX_OID_LEN]; - uint8_t oidlen; + psAsnOid_t asnOid; oid_e noid; # ifdef USE_FULL_CERT_PARSE psSize_t subExtLen; const unsigned char *subSave; int32_t nc = 0; +# ifdef USE_CERT_POLICY_EXTENSIONS x509PolicyInformation_t *pPolicy; const unsigned char *policiesEnd; +# endif # endif /* USE_FULL_CERT_PARSE */ end = p + inlen; @@ -3580,12 +3870,12 @@ KNOWN_EXT: psTraceCrypto("Malformed extension length\n"); return PS_PARSE_FAIL; } - if ((oidlen = asnParseOid(p, len, oid)) < 1) + if (asnCopyOid(p, len, asnOid) < 1) { psTraceCrypto("Malformed extension OID\n"); return PS_PARSE_FAIL; } - noid = psFindOid(oid, oidlen); + noid = psOidToEnum(asnOid); p += len; /* Possible boolean value here for 'critical' id. It's a failure if a @@ -3812,12 +4102,12 @@ KNOWN_EXT: psTraceCrypto("Malformed extension length\n"); return PS_PARSE_FAIL; } - if ((oidlen = asnParseOid(p, len, oid)) < 1) + if (asnCopyOid(p, len, asnOid) < 1) { psTraceCrypto("Malformed extension OID\n"); return PS_PARSE_FAIL; } - noid = psFindOid(oid, oidlen); + noid = psOidToEnum(asnOid); p += len; if (fullExtLen < (uint32) (p - save)) { @@ -3850,9 +4140,14 @@ KNOWN_EXT: extensions->ekuFlags |= EXT_KEY_USAGE_ANY; break; default: - psTraceCrypto("WARNING: Unknown EXT_KEY_USAGE:"); - psTraceOid(oid, oidlen); - break; + { +# ifdef USE_CRYPTO_TRACE + char buffer[MAX_OID_PRINTED_LEN]; + psTraceStrCrypto("WARNING: Unknown EXT_KEY_USAGE: %s\n", + psSprintAsnOid(asnOid, buffer)); +# endif /* USE_CRYPTO_TRACE */ + break; + } } /* end switch */ } break; @@ -4174,6 +4469,7 @@ KNOWN_EXT: break; # ifdef USE_FULL_CERT_PARSE +# ifdef USE_CERT_POLICY_EXTENSIONS case OID_ENUM(id_ce_certificatePolicies): /* certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation @@ -4241,6 +4537,7 @@ KNOWN_EXT: p += len; break; +# endif /* USE_CERT_POLICY_EXTENSIONS */ case OID_ENUM(id_ce_issuerAltName): if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0) { @@ -4270,8 +4567,11 @@ KNOWN_EXT: /* Unsupported or skipping because USE_FULL_CERT_PARSE undefd */ if (critical) { - psTraceCrypto("Unsupported critical ext encountered: "); - psTraceOid(oid, oidlen); +# ifdef USE_CRYPTO_TRACE + char buffer[MAX_OID_PRINTED_LEN]; + psTraceStrCrypto("Unsupported critical ext encountered: %s\n", + psSprintAsnOid(asnOid, buffer)); +# endif /* USE_CRYPTO_TRACE */ # ifndef ALLOW_UNKNOWN_CRITICAL_EXTENSIONS _psTrace("An unsupported critical extension was " "encountered. X.509 specifications say " @@ -4898,6 +5198,11 @@ oid_parsing_done: { case ASN_BMPSTRING: { +# ifndef USE_ASN_BMPSTRING_DN_ATTRIBS + psTraceCrypto("Error: BMPString not supported in DN attributes\n"); + psTraceCrypto("Please enable USE_ASN_BMPSTRING in cryptoConfig.h\n"); + return PS_UNSUPPORTED_FAIL; +# else /* MatrixSSL generally uses single byte character string formats. This function converts ASN_BMPSTRING to UTF-8 for further handling. */ @@ -4933,6 +5238,7 @@ oid_parsing_done: p = p + llen; llen = (uint16_t) length + DN_NUM_TERMINATING_NULLS; break; +# endif /* USE_ASN_BMPSTRING_DN_ATTRIBS */ } case ASN_PRINTABLESTRING: case ASN_UTF8STRING: @@ -5440,6 +5746,10 @@ int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert, opts.msgIsDigestInfo = PS_FALSE; } # endif /* USE_ED25519 */ +# if defined(USE_ROT_CRYPTO) && (defined(USE_ROT_ECC) || defined(USE_ROT_RSA)) + tbs = sc->tbsCertStart; + tbsLen = sc->tbsCertLen; +# endif res = psVerifySig(NULL, tbs, tbsLen, diff --git a/crypto/keyformat/x509.h b/crypto/keyformat/x509.h index 96ff597..84ea902 100644 --- a/crypto/keyformat/x509.h +++ b/crypto/keyformat/x509.h @@ -264,8 +264,7 @@ typedef struct x509PolicyQualifierInfo_t typedef struct x509PolicyInformation_t { - uint32_t *policyOid; - psSize_t policyOidLen; + psAsnOid_t *policyAsnOid; x509PolicyQualifierInfo_t *qualifiers; struct x509PolicyInformation_t *next; } x509PolicyInformation_t; @@ -283,10 +282,8 @@ typedef struct x509policyConstraints_t typedef struct x509policyMappings_t { - uint32_t *issuerDomainPolicy; - uint32_t *subjectDomainPolicy; - psSize_t issuerDomainPolicyLen; - psSize_t subjectDomainPolicyLen; + psAsnOid_t *issuerDomainPolicy; + psAsnOid_t *subjectDomainPolicy; struct x509policyMappings_t *next; } x509policyMappings_t; @@ -624,7 +621,7 @@ typedef struct psCert int32 certAlgorithm; /* TBSCertificate sig alg OID */ unsigned char *signature; psSize_t signatureLen; -# ifdef USE_ED25519 +# if defined(USE_ED25519) || defined(USE_ROT_ECC) || defined(USE_ROT_RSA) unsigned char *tbsCertStart; psSizeL_t tbsCertLen; # endif @@ -775,7 +772,7 @@ extern int32_t psX509GetOnelineDN(const x509DNattributes_t *DN, /* The OCSP structure members point directly into an OCSPResponse stream. They are validated immediately after the parse so if a change request requires these fields to persist, this will all have to change */ -typedef struct +typedef struct psOcspSingleResponse { uint16_t certIdHashAlg; /* hashAlgorithm in CertID */ const unsigned char *certIdNameHash; @@ -793,7 +790,7 @@ typedef struct # define MAX_OCSP_RESPONSES 3 -typedef struct +typedef struct psOcspResponse { const unsigned char *responderName; const unsigned char *responderKeyHash; diff --git a/crypto/layer/layer.h b/crypto/layer/layer.h index 4c64065..08a0d39 100644 --- a/crypto/layer/layer.h +++ b/crypto/layer/layer.h @@ -5,7 +5,7 @@ * Header file to determine crypto algorithm provider. */ /* - * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) 2013-2018 INSIDE Secure Corporation * Copyright (c) PeerSec Networks, 2002-2011 * All Rights Reserved * @@ -216,6 +216,63 @@ /* Common for CL CRYPTO and FIPS CRYPTO */ +/******************************************************************************/ + +# ifdef USE_ROT_CRYPTO +/* Inside Secure Root-of-Trust (RoT) based crypto implementation. */ + +# ifdef USE_SHA256 +# ifdef USE_MATRIX_SHA256 +# define USE_ROT_SHA256 +# define USE_ROT_HMAC_SHA256 +# undef USE_MATRIX_SHA256 +# undef USE_MATRIX_HMAC_SHA256 +# endif /* USE_MATRIX_SHA256 */ +# endif /* USE_SHA256 */ + +# ifdef USE_SHA384 +# ifdef USE_MATRIX_SHA384 +# define USE_ROT_SHA384 +# define USE_ROT_HMAC_SHA384 +# undef USE_MATRIX_SHA384 +# undef USE_MATRIX_HMAC_SHA384 +# endif /* USE_MATRIX_SHA384 */ +# endif /* USE_SHA384 */ + +# ifdef USE_SHA512 +# ifdef USE_MATRIX_SHA512 +# define USE_ROT_SHA512 +# define USE_ROT_HMAC_SHA512 +# undef USE_MATRIX_SHA512 +# undef USE_MATRIX_HMAC_SHA512 +# endif /* USE_MATRIX_SHA512 */ +# endif /* USE_SHA512 */ + +# ifdef USE_AES_GCM +# ifdef USE_MATRIX_AES_GCM +# define USE_ROT_AES_GCM +# define USE_ROT_AES_BLOCK +# define USE_ROT_AES_CBC +# undef USE_MATRIX_AES_GCM +# undef USE_MATRIX_AES_BLOCK +# undef USE_MATRIX_AES_CBC +# endif +# endif /* USE_GCM */ + +# if defined(USE_RSA) +# if defined(USE_ROT_RSA) +# undef USE_MATRIX_RSA +# endif /* USE_ROT_RSA */ +# endif /* USE_RSA */ + +# if defined(USE_ECC) +# if defined(USE_ROT_ECC) +# undef USE_MATRIX_ECC +# endif /* USE_ROT_ECC */ +# endif /* USE_ECC */ + +# endif /* USE_ROT_CRYPTO */ + # ifdef USE_OPENSSL_CRYPTO /******************************************************************************/ /** diff --git a/crypto/layer/matrix.c b/crypto/layer/matrix.c index 175c651..73a3ff2 100644 --- a/crypto/layer/matrix.c +++ b/crypto/layer/matrix.c @@ -5,7 +5,7 @@ * Matrix Crypto Initialization and utility layer. */ /* - * Copyright (c) 2013-2017 INSIDE Secure Corporation + * Copyright (c) 2013-2018 INSIDE Secure Corporation * Copyright (c) PeerSec Networks, 2002-2011 * All Rights Reserved * @@ -34,6 +34,10 @@ #include "../cryptoImpl.h" +#ifdef USE_ROT_CRYPTO +# include "../../crypto-rot/rotCommon.h" +#endif + /******************************************************************************/ /** Open (initialize) the Crypto module. @@ -75,6 +79,31 @@ int32_t psCryptoOpen(const char *config) return PS_SELFTEST_FAILED; } #endif /* USE_FLPS_BINDING */ +#ifdef USE_ROT_ECC + /* Pre-allocate domain assets for all ECC curves supported by the + compile-time configuration. */ +# ifdef USE_SECP256R1 + if (psRotLoadCurve(IANA_SECP256R1, NULL) != PS_SUCCESS) + { + psError("psRotLoadCurve failed during psCryptoOpen\n"); + return PS_FAILURE; + } +# endif /* USE_SECP256R1 */ +# ifdef USE_SECP384R1 + if (psRotLoadCurve(IANA_SECP384R1, NULL) != PS_SUCCESS) + { + psError("psRotLoadCurve failed during psCryptoOpen\n"); + return PS_FAILURE; + } +# endif /* USE_SECP384R1 */ +# ifdef USE_SECP521R1 + if (psRotLoadCurve(IANA_SECP521R1, NULL) != PS_SUCCESS) + { + psError("psRotLoadCurve failed during psCryptoOpen\n"); + return PS_FAILURE; + } +# endif /* USE_SECP521R1 */ +#endif /* USE_ROT_ECC */ #ifdef USE_LIBSODIUM_CRYPTO if (sodium_init() == -1) { @@ -103,6 +132,20 @@ int32_t psCryptoOpen(const char *config) void psCryptoClose(void) { +#ifdef USE_ROT_ECC +# ifdef USE_SECP256R1 + psRotFreeCurveAsset(IANA_SECP256R1); +# endif +# ifdef USE_SECP384R1 + psRotFreeCurveAsset(IANA_SECP384R1); +# endif +# ifdef USE_SECP521R1 + psRotFreeCurveAsset(IANA_SECP521R1); +# endif +# ifdef DEBUG_ROT_ASSETS + psRotFreeAllAssets(); +# endif +#endif if (*g_config == 'Y') { *g_config = 'N'; diff --git a/crypto/pubkey/ecc_curve_config.c b/crypto/pubkey/ecc_curve_config.c index 515c95b..96205ce 100644 --- a/crypto/pubkey/ecc_curve_config.c +++ b/crypto/pubkey/ecc_curve_config.c @@ -36,7 +36,7 @@ #include "../cryptoImpl.h" -#ifdef USE_MATRIX_ECC +#if defined(USE_MATRIX_ECC) || defined(USE_ROT_ECC) int32_t getEccParamById(psCurve16_t curveId, const psEccCurve_t **curve) { @@ -64,18 +64,18 @@ int32_t getEccParamById(psCurve16_t curveId, const psEccCurve_t **curve) /** User set list of curves they want to support. - This method will put the largest bit strength first in the list. - @param[in] curves Flags indicating which curves to use. */ void userSuppliedEccList(unsigned char *curveList, uint8_t *len, uint32_t curves) { const psEccCurve_t *curve; uint8_t listLen = 0; -# ifdef USE_SECP521R1 - if (curves & IS_SECP521R1) + /* Prefer 256-bit and 384-bit curves over 521-bit ones. + They are secure enough, and faster. */ +# ifdef USE_SECP256R1 + if (curves & IS_SECP256R1) { - if (getEccParamById(IANA_SECP521R1, &curve) == 0) + if (getEccParamById(IANA_SECP256R1, &curve) == 0) { if (listLen < (*len - 2)) { @@ -85,10 +85,10 @@ void userSuppliedEccList(unsigned char *curveList, uint8_t *len, uint32_t curves } } # endif -# ifdef USE_BRAIN512R1 - if (curves & IS_BRAIN512R1) +# ifdef USE_BRAIN256R1 + if (curves & IS_BRAIN256R1) { - if (getEccParamById(IANA_BRAIN512R1, &curve) == 0) + if (getEccParamById(IANA_BRAIN256R1, &curve) == 0) { if (listLen < (*len - 2)) { @@ -124,10 +124,10 @@ void userSuppliedEccList(unsigned char *curveList, uint8_t *len, uint32_t curves } } # endif -# ifdef USE_SECP256R1 - if (curves & IS_SECP256R1) +# ifdef USE_SECP521R1 + if (curves & IS_SECP521R1) { - if (getEccParamById(IANA_SECP256R1, &curve) == 0) + if (getEccParamById(IANA_SECP521R1, &curve) == 0) { if (listLen < (*len - 2)) { @@ -137,10 +137,10 @@ void userSuppliedEccList(unsigned char *curveList, uint8_t *len, uint32_t curves } } # endif -# ifdef USE_BRAIN256R1 - if (curves & IS_BRAIN256R1) +# ifdef USE_BRAIN512R1 + if (curves & IS_BRAIN512R1) { - if (getEccParamById(IANA_BRAIN256R1, &curve) == 0) + if (getEccParamById(IANA_BRAIN512R1, &curve) == 0) { if (listLen < (*len - 2)) { @@ -228,5 +228,5 @@ uint32_t compiledInEcFlags(void) return ecFlags; } -#endif /* USE_MATRIX_ECC */ +#endif /* USE_MATRIX_ECC || USE_ROT_ECC */ diff --git a/crypto/pubkey/ecc_parse_mem.c b/crypto/pubkey/ecc_parse_mem.c index 5bf2fff..e8eaaf9 100644 --- a/crypto/pubkey/ecc_parse_mem.c +++ b/crypto/pubkey/ecc_parse_mem.c @@ -113,10 +113,10 @@ int32_t getEcPubKey(psPool_t *pool, const unsigned char **pp, psSize_t len, Standard form - SHA-1 hash of the value of the BIT STRING subjectPublicKey [excluding the tag, length, and number of unused bits] */ - psSha1PreInit(&dc.sha1); - psSha1Init(&dc.sha1); - psSha1Update(&dc.sha1, p, arcLen); - psSha1Final(&dc.sha1, sha1KeyHash); + psSha1PreInit(&dc.u.sha1); + psSha1Init(&dc.u.sha1); + psSha1Update(&dc.u.sha1, p, arcLen); + psSha1Final(&dc.u.sha1, sha1KeyHash); # endif /* Note arcLen could again be zero here */ diff --git a/crypto/pubkey/pubkey.h b/crypto/pubkey/pubkey.h index d66188b..7af28d9 100644 --- a/crypto/pubkey/pubkey.h +++ b/crypto/pubkey/pubkey.h @@ -37,6 +37,13 @@ /******************************************************************************/ +# ifdef USE_ROT_CRYPTO +# include "../../crypto-rot/rot/include/api_val_asset.h" +# endif + +# ifdef USE_ROT_CRYPTO +# include "pubkey_rot.h" +# endif # include "pubkey_matrix.h" # ifdef USE_OPENSSL_CRYPTO # include "pubkey_openssl.h" @@ -226,6 +233,9 @@ typedef struct psPool_t *pool; psSize_t keysize; /* in bytes. 512 max for RSA 4096 */ uint8_t type; /* PS_RSA, PS_ECC, PS_DH */ +# ifdef USE_ROT_CRYPTO + int32_t rotSigAlg; +# endif } psPubKey_t; # define PS_SIGN_OPTS_ECDSA_INCLUDE_SIZE (1ULL << 0) @@ -334,11 +344,14 @@ typedef struct int32_t rsaPssHashAlg; psSize_t rsaPssHashLen; psSize_t rsaPssSaltLen; - psBool_t useRsaPss; # endif + psBool_t useRsaPss; + /* The signed data was a DigestInfo structure. This is only relevant for RSA. */ psBool_t msgIsDigestInfo; + /* Skip pre-hashing of input data before verifying the sig? */ + psBool_t noPreHash; } psVerifyOptions_t; typedef psVerifyOptions_t psVerifySigOptions_t; diff --git a/crypto/pubkey/pubkey_matrix.h b/crypto/pubkey/pubkey_matrix.h index f42066f..39d3395 100644 --- a/crypto/pubkey/pubkey_matrix.h +++ b/crypto/pubkey/pubkey_matrix.h @@ -45,6 +45,12 @@ typedef struct psPool_t *pool; psSize_t size; /* Size of the key in bytes */ uint8_t optimized; /* Set if optimized */ +# ifdef USE_ROT_RSA + ValAssetId_t privSigAsset; + ValAssetId_t pubSigAsset; + ValAssetId_t privEncAsset; + ValAssetId_t pubEncAsset; +# endif } psRsaKey_t; # endif @@ -85,6 +91,12 @@ typedef struct psPool_t *pool; } psEccPoint_t; +typedef enum +{ + ps_ecc_key_type_ecdsa = 0, + ps_ecc_key_type_ecdhe = 1 +} psEccKeyType_t; + typedef struct { pstm_int k; /* The private key */ @@ -92,8 +104,37 @@ typedef struct const psEccCurve_t *curve; /* pointer to named curve */ psPool_t *pool; uint8_t type; /* Type of key, PS_PRIVKEY or PS_PUBKEY */ +# ifdef USE_ROT_ECC + ValAssetId_t pubAsset; + ValAssetId_t domainAsset; + ValAssetId_t privAsset; + psBool_t longTermPrivAsset; + psEccKeyType_t rotKeyType; + unsigned char pubValue[64]; +# endif } psEccKey_t; +# ifdef USE_ROT_ECC +/* RoT-specific structure for the ECC curves. */ +typedef struct +{ + uint32_t CurveBits; + const uint8_t * P_p; + uint32_t PLen; + const uint8_t * A_p; + uint32_t ALen; + const uint8_t * B_p; + uint32_t BLen; + const uint8_t * ECPointX_p; + uint32_t ECPointXLen; + const uint8_t * ECPointY_p; + uint32_t ECPointYLen; + const uint8_t * Order_p; + uint32_t OrderLen; + const uint8_t Cofactor; +} psRotCurve_t; +# endif /* USE_ROT_ECC */ + # endif /******************************************************************************/ diff --git a/crypto/pubkey/pubkey_parse_file.c b/crypto/pubkey/pubkey_parse_file.c index cbb01f0..74db63f 100644 --- a/crypto/pubkey/pubkey_parse_file.c +++ b/crypto/pubkey/pubkey_parse_file.c @@ -170,15 +170,16 @@ static int32 pkcs8parse_unknown( /******************************************************************************/ /** - Parse PKCS#8 format keys (from DER formatted binary) + Parse PKCS #8 format keys (from DER formatted binary) 'key' is dynamically allocated and must be freed with psFreePubKey() if no error is returned from this API Unencrypted private keys are supported if 'pass' is NULL - Encrypted private keys are supported if 'pass' is non-null for the - des-EDE3-CBC algorithm only (3DES). Other PKCS#5 symmetric algorithms - are not supported. + Encrypted private keys are supported if 'pass' is non-null only for the + des-ede3-cbc algorithm (3DES) with PBES2 (PKCS #8 v2.0). + This protection matches OpenSSL's pkcs8 option -v2 des3. + Other PKCS #5 symmetric algorithms are not supported. @return < 0 on error, private keysize in bytes on success. */ @@ -339,11 +340,16 @@ psRes_t psPkcs8ParsePrivBin(psPool_t *pool, psTraceCrypto("PKCS#8 padding error\n"); return PS_FAILURE; } + /* Padding errors are considered as "PS_AUTH_FAIL", + because the padding is incorrect with overwhelming probability + if password was incorrect. The error may also be corrupt + bytes in PKCS #8 der encododed material. Distinguishing between + corrupted input and wrong password is not always possible. */ plen = (unsigned char) p[len - 1]; if (plen < 1 || plen > 16) { psTraceCrypto("PKCS#8 padding error\n"); - return PS_FAILURE; + return PS_AUTH_FAIL; } /* coverity[dead_error_condition] */ /* With the current value for MIN_ECC_BITS and MIN_RSA_BITS @@ -360,7 +366,7 @@ psRes_t psPkcs8ParsePrivBin(psPool_t *pool, if (p[len - i - 1] != (unsigned char) plen) { psTraceCrypto("PKCS#8 padding error\n"); - return PS_FAILURE; + return PS_AUTH_FAIL; } } @@ -401,13 +407,18 @@ psRes_t psPkcs8ParsePrivBin(psPool_t *pool, psTraceCrypto("Couldn't parse PKCS#8 algorithm identifier\n"); return PS_FAILURE; } -# ifdef USE_ECC - if (oi != OID_ECDSA_KEY_ALG && oi != OID_RSA_KEY_ALG) + + if (oi != OID_ECDSA_KEY_ALG + && oi != OID_RSA_KEY_ALG + && oi != OID_RSASSA_PSS) { return pkcs8parse_unknown(pool, (unsigned char *)buf, size, key); } - if (oi == OID_ECDSA_KEY_ALG) + + switch (oi) { +# ifdef USE_ECC + case OID_ECDSA_KEY_ALG: /* Still a curve identifier sitting as param in the SEQUENCE */ if ((uint32) (end - p) < 1 || *p++ != ASN_OID) { @@ -431,13 +442,20 @@ psRes_t psPkcs8ParsePrivBin(psPool_t *pool, psTraceCrypto("Unsupported EC curve OID\n"); return PS_UNSUPPORTED_FAIL; } - } -# else - if (oi != OID_RSA_KEY_ALG || plen != 0) - { + break; +# endif +# ifdef USE_RSA +# ifdef USE_PKCS1_PSS + case OID_RSASSA_PSS: + break; +# endif /* USE_PKCS1_PSS */ + case OID_RSA_KEY_ALG: + break; +# endif /* USE_RSA */ + default: return pkcs8parse_unknown(pool, (unsigned char *)buf, size, key); } -# endif + /* PrivateKey Octet Stream */ if ((uint32) (end - p) < 1) { @@ -453,7 +471,7 @@ psRes_t psPkcs8ParsePrivBin(psPool_t *pool, } /* Note len can be zero here */ # ifdef USE_RSA - if (oi == OID_RSA_KEY_ALG) + if (oi == OID_RSA_KEY_ALG || oi == OID_RSASSA_PSS) { /* Create the actual key here from the octet string */ psRsaInitKey(pool, &key->key.rsa); diff --git a/crypto/pubkey/pubkey_parse_mem.c b/crypto/pubkey/pubkey_parse_mem.c index d26a965..31cbbe7 100644 --- a/crypto/pubkey/pubkey_parse_mem.c +++ b/crypto/pubkey/pubkey_parse_mem.c @@ -61,61 +61,78 @@ static int32_t psTryParsePrivKeyMem(psPool_t *pool, const unsigned char *keyBuf, int32 keyBufLen, const char *password, - psPubKey_t *privkey) + psPubKey_t *privKey) { int32_t rc; #ifdef USE_RSA /* Examine data to ensure parses which could not succeed are not tried. */ if (possiblyRSAKey(keyBuf, keyBufLen)) { - rc = psRsaParsePkcs1PrivKey(pool, keyBuf, keyBufLen, &privkey->key.rsa); +# ifdef USE_ROT_RSA + if (privKey->rotSigAlg == 0) + { + privKey->key.rsa.rotSigAlg = OID_SHA256_RSA_SIG; + } + else + { + privKey->key.rsa.rotSigAlg = privKey->rotSigAlg; + } +# endif + rc = psRsaParsePkcs1PrivKey(pool, + keyBuf, + keyBufLen, + &privKey->key.rsa); if (rc >= PS_SUCCESS) { - privkey->type = PS_RSA; - privkey->keysize = psRsaSize(&privkey->key.rsa); - privkey->pool = pool; - return 1; /* RSA */ + privKey->type = PS_RSA; + privKey->keysize = psRsaSize(&privKey->key.rsa); + privKey->pool = pool; + return PS_RSA; } } #endif /* USE_RSA */ #ifdef USE_ECC - rc = psEccParsePrivKey(pool, keyBuf, keyBufLen, &privkey->key.ecc, NULL); + rc = psEccParsePrivKey(pool, + keyBuf, + keyBufLen, + &privKey->key.ecc, + NULL); if (rc >= PS_SUCCESS) { - privkey->type = PS_ECC; - privkey->keysize = psEccSize(&privkey->key.ecc); - privkey->pool = pool; - return 2; /* ECC */ + privKey->type = PS_ECC; + privKey->keysize = psEccSize(&privKey->key.ecc); + privKey->pool = pool; + return PS_ECC; } # ifdef USE_ED25519 rc = psEd25519ParsePrivKey(pool, keyBuf, keyBufLen, - &privkey->key.ed25519); + &privKey->key.ed25519); if (rc >= PS_SUCCESS) { - privkey->type = PS_ED25519; - privkey->keysize = 32; - privkey->pool = pool; - return 3; + privKey->type = PS_ED25519; + privKey->keysize = 32; + privKey->pool = pool; + return PS_ED25519; } # endif /* USE_ED25519 */ #endif /* USE_ECC */ #ifdef USE_PKCS8 if (psPkcs8ParsePrivBin(pool, keyBuf, keyBufLen, - (char*)password, privkey) >= PS_SUCCESS) + (char*)password, privKey) >= PS_SUCCESS) { # ifdef USE_RSA - if (privkey->type == PS_RSA) + if (privKey->type == PS_RSA) { - return 1; /* RSA */ + return PS_RSA; } # endif /* USE_RSA */ # ifdef USE_ECC - if (privkey->type == PS_ECC) + if (privKey->type == PS_ECC) { - return 2; /* ECC */ + return PS_ECC; } # endif /* USE_ECC */ @@ -141,20 +158,20 @@ int32_t psParseUnknownPrivKeyMem(psPool_t *pool, const unsigned char *keyBuf, int32 keyBufLen, const char *password, - psPubKey_t *privkey) + psPubKey_t *privKey) { int32_t keytype; if (keyBuf == NULL || keyBufLen <= 0) return PS_ARG_FAIL; - privkey->keysize = 0; + privKey->keysize = 0; keytype = psTryParsePrivKeyMem(pool, keyBuf, keyBufLen, password, - privkey); + privKey); if (keytype < 0) { @@ -252,6 +269,7 @@ psParseUnknownPubKeyMem(psPool_t *pool, int32_t rc; unsigned char *data; psSizeL_t data_len; + psBool_t mustFreeData = PS_TRUE; # if defined USE_RSA || defined USE_ECC unsigned char hashBuf[SHA1_HASH_SIZE]; # endif @@ -268,6 +286,7 @@ psParseUnknownPubKeyMem(psPool_t *pool, /* Not PEM or PEM decoding not supported. Try DER. */ data = (unsigned char *)keyBuf; data_len = keyBufLen; + mustFreeData = PS_FALSE; } # ifdef USE_RSA @@ -275,6 +294,10 @@ psParseUnknownPubKeyMem(psPool_t *pool, (const unsigned char **)&data, data_len, &pubkey->key.rsa, hashBuf); + if (rc == PS_SUCCESS) + { + pubkey->type = PS_RSA; + } # endif # ifdef USE_ECC if (rc < PS_SUCCESS) @@ -287,11 +310,17 @@ psParseUnknownPubKeyMem(psPool_t *pool, rc = psEccParsePrivKey(pool, data, data_len, &pubkey->key.ecc, NULL); } + if (rc == PS_SUCCESS) + { + pubkey->type = PS_ECC; + } } # endif - if (data != keyBuf) + + if (mustFreeData) { + psAssert(data != keyBuf); psFree(data, pool); } @@ -301,13 +330,13 @@ psParseUnknownPubKeyMem(psPool_t *pool, # else /* USE_PRIVATE_KEY_PARSING */ PSPUBLIC int32_t psParseUnknownPrivKeyMem(psPool_t *pool, const unsigned char *keyBuf, int32 keyBufLen, - const char *password, psPubKey_t *privkey) + const char *password, psPubKey_t *privKey) { PS_VARIABLE_SET_BUT_UNUSED(pool); PS_VARIABLE_SET_BUT_UNUSED(keyBuf); PS_VARIABLE_SET_BUT_UNUSED(keyBufLen); PS_VARIABLE_SET_BUT_UNUSED(password); - PS_VARIABLE_SET_BUT_UNUSED(privkey); + PS_VARIABLE_SET_BUT_UNUSED(privKey); return -1; /* Not implemented */ } # endif /* USE_PRIVATE_KEY_PARSING */ diff --git a/crypto/pubkey/pubkey_sign.c b/crypto/pubkey/pubkey_sign.c index d058343..57efe9e 100644 --- a/crypto/pubkey/pubkey_sign.c +++ b/crypto/pubkey/pubkey_sign.c @@ -203,7 +203,8 @@ int32_t psSignHash(psPool_t *pool, } break; # endif /* USE_ECC */ -# ifdef USE_PKCS1_PSS +# ifdef USE_RSA +# ifdef USE_PKCS1_PSS case OID_RSASSA_PSS: if (privKey->type == PS_RSA) { @@ -211,8 +212,7 @@ int32_t psSignHash(psPool_t *pool, in, inLen, out, outLen, opts); } break; -# endif /* USE_PKCS1_PSS */ -# ifdef USE_RSA +# endif /* USE_PKCS1_PSS */ case OID_SHA256_RSA_SIG: case OID_SHA384_RSA_SIG: case OID_SHA512_RSA_SIG: @@ -251,6 +251,11 @@ int32_t psSign(psPool_t *pool, psTraceBytes("psSign in", in, inLen); # endif + if (opts && (opts->flags & PS_SIGN_OPTS_USE_PREALLOCATED_OUTBUF)) + { + sigOut = *out; + } + switch (sigAlg) { # ifdef USE_ED25519 @@ -326,12 +331,12 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, { return PS_OUTPUT_LENGTH; } - psMd2Init(&hash.md2); - if (psMd2Update(&hash.md2, dataBegin, dataLen) < 0) + psMd2Init(&hash.u.md2); + if (psMd2Update(&hash.u.md2, dataBegin, dataLen) < 0) { return PS_FAILURE; } - if (psMd2Final(&hash.md2, hashOut) < 0) + if (psMd2Final(&hash.u.md2, hashOut) < 0) { return PS_FAILURE; } @@ -343,15 +348,16 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, { return PS_OUTPUT_LENGTH; } - if (psMd5Init(&hash.md5) < 0) + if (psMd5Init(&hash.u.md5) < 0) { return PS_FAILURE; } - psMd5Update(&hash.md5, dataBegin, dataLen); - psMd5Final(&hash.md5, hashOut); + psMd5Update(&hash.u.md5, dataBegin, dataLen); + psMd5Final(&hash.u.md5, hashOut); *hashOutLen = MD5_HASH_SIZE; break; # endif /* ENABLE_MD5_SIGNED_CERTS */ +# ifdef USE_SHA1 case OID_SHA1_RSA_SIG: case OID_SHA1_RSA_SIG2: case OID_SHA1_ECDSA_SIG: @@ -359,12 +365,13 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, { return PS_OUTPUT_LENGTH; } - psSha1PreInit(&hash.sha1); - psSha1Init(&hash.sha1); - psSha1Update(&hash.sha1, dataBegin, dataLen); - psSha1Final(&hash.sha1, hashOut); + psSha1PreInit(&hash.u.sha1); + psSha1Init(&hash.u.sha1); + psSha1Update(&hash.u.sha1, dataBegin, dataLen); + psSha1Final(&hash.u.sha1, hashOut); *hashOutLen = SHA1_HASH_SIZE; break; +#endif #ifdef USE_SHA224 case OID_SHA224_RSA_SIG: case OID_SHA224_ECDSA_SIG: @@ -372,10 +379,10 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, { return PS_OUTPUT_LENGTH; } - psSha224PreInit(&hash.sha256); - psSha224Init(&hash.sha256); - psSha224Update(&hash.sha256, dataBegin, dataLen); - psSha224Final(&hash.sha256, hashOut); + psSha224PreInit(&hash.u.sha256); + psSha224Init(&hash.u.sha256); + psSha224Update(&hash.u.sha256, dataBegin, dataLen); + psSha224Final(&hash.u.sha256, hashOut); *hashOutLen = SHA224_HASH_SIZE; break; #endif /* USE_SHA224 */ @@ -385,10 +392,10 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, { return PS_OUTPUT_LENGTH; } - psSha256PreInit(&hash.sha256); - psSha256Init(&hash.sha256); - psSha256Update(&hash.sha256, dataBegin, dataLen); - psSha256Final(&hash.sha256, hashOut); + psSha256PreInit(&hash.u.sha256); + psSha256Init(&hash.u.sha256); + psSha256Update(&hash.u.sha256, dataBegin, dataLen); + psSha256Final(&hash.u.sha256, hashOut); *hashOutLen = SHA256_HASH_SIZE; break; # ifdef USE_SHA384 @@ -398,10 +405,10 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, { return PS_OUTPUT_LENGTH; } - psSha384PreInit(&hash.sha384); - psSha384Init(&hash.sha384); - psSha384Update(&hash.sha384, dataBegin, dataLen); - psSha384Final(&hash.sha384, hashOut); + psSha384PreInit(&hash.u.sha384); + psSha384Init(&hash.u.sha384); + psSha384Update(&hash.u.sha384, dataBegin, dataLen); + psSha384Final(&hash.u.sha384, hashOut); *hashOutLen = SHA384_HASH_SIZE; break; # endif @@ -412,10 +419,10 @@ psRes_t psComputeHashForSig(const unsigned char *dataBegin, { return PS_OUTPUT_LENGTH; } - psSha512PreInit(&hash.sha512); - psSha512Init(&hash.sha512); - psSha512Update(&hash.sha512, dataBegin, dataLen); - psSha512Final(&hash.sha512, hashOut); + psSha512PreInit(&hash.u.sha512); + psSha512Init(&hash.u.sha512); + psSha512Update(&hash.u.sha512, dataBegin, dataLen); + psSha512Final(&hash.u.sha512, hashOut); *hashOutLen = SHA512_HASH_SIZE; break; # endif diff --git a/crypto/pubkey/pubkey_verify.c b/crypto/pubkey/pubkey_verify.c index 407da2b..e558c33 100644 --- a/crypto/pubkey/pubkey_verify.c +++ b/crypto/pubkey/pubkey_verify.c @@ -2,7 +2,7 @@ * @file pubkey_verify.c * @version $Format:%h%d$ * - * Algorithm-independent verification API. + * Algorithm-independent signature verification API. */ /* * Copyright (c) 2013-2018 INSIDE Secure Corporation @@ -217,7 +217,7 @@ psRes_t psHashDataAndVerifySig(psPool_t *pool, return rc; } -# ifdef USE_PKCS1_PSS +# if defined(USE_RSA) && defined(USE_PKCS1_PSS) static int32_t get_pss_hash_sig_alg(psVerifyOptions_t *opts) { @@ -251,9 +251,10 @@ psRes_t psVerify(psPool_t *pool, *verifyResult = PS_FALSE; +# if defined(USE_RSA) && defined(USE_PKCS1_PSS) if (opts && opts->useRsaPss) { -# if defined (USE_PKCS1_PSS) && defined(USE_CL_RSA) +# ifdef USE_CL_RSA /* The crypto-cl API for RSA-PSS verification does not support pre-hashing. */ needPreHash = PS_FALSE; @@ -267,6 +268,7 @@ psRes_t psVerify(psPool_t *pool, signatureAlgorithm = get_pss_hash_sig_alg(opts); } } +# endif /* RSA && PKCS1_PSS */ # ifdef USE_ED25519 if (signatureAlgorithm == OID_ED25519_KEY_ALG) diff --git a/crypto/pubkey/rsa_parse_mem.c b/crypto/pubkey/rsa_parse_mem.c index 116204b..fcda030 100644 --- a/crypto/pubkey/rsa_parse_mem.c +++ b/crypto/pubkey/rsa_parse_mem.c @@ -71,10 +71,10 @@ int32_t psRsaParseAsnPubKey(psPool_t *pool, Standard RSA form - SHA-1 hash of the value of the BIT STRING subjectPublicKey [excluding the tag, length, and number of unused bits] */ - psSha1PreInit(&dc.sha1); - psSha1Init(&dc.sha1); - psSha1Update(&dc.sha1, p, keylen - 1); - psSha1Final(&dc.sha1, sha1KeyHash); + psSha1PreInit(&dc.u.sha1); + psSha1Init(&dc.u.sha1); + psSha1Update(&dc.u.sha1, p, keylen - 1); + psSha1Final(&dc.u.sha1, sha1KeyHash); # endif if (getAsnSequence(&p, keylen, &seqlen) < 0) diff --git a/crypto/pubkey/rsa_pub.c b/crypto/pubkey/rsa_pub.c index 26fc4bd..8f62f5a 100644 --- a/crypto/pubkey/rsa_pub.c +++ b/crypto/pubkey/rsa_pub.c @@ -372,6 +372,14 @@ psRes_t psRsaPssVerify(psPool_t *pool, psFree(em, pool); return rc; } +# ifdef DEBUG_RSA_PSS + psTraceBytes("psRsaPssVerify in", msgIn, msgInLen); + psTraceBytes("psRsaPssVerify sig", sig, sigLen); + psTraceIntCrypto("hashlen: %hu\n", + (uint16_t)psPssHashAlgToHashLen(opts->rsaPssHashAlg)); + psTraceIntCrypto("saltlen: %hu\n", + opts->rsaPssSaltLen); +# endif rc = psPkcs1PssDecode(pool, msgIn, msgInLen, diff --git a/crypto/symmetric/aes_matrix.h b/crypto/symmetric/aes_matrix.h index a68e3a1..b0db6bb 100644 --- a/crypto/symmetric/aes_matrix.h +++ b/crypto/symmetric/aes_matrix.h @@ -91,6 +91,35 @@ typedef struct } psAesGcm_t; # endif +# ifdef USE_ROT_AES_GCM +# include "../../crypto-rot/rot/include/api_val.h" +typedef struct +{ + ValSymContextPtr_t ctx; + unsigned char aad[32]; + psSizeL_t aadLen; + unsigned char tag[16]; + psSizeL_t tagLen; + unsigned char key[32]; + psSizeL_t keyLen; +} psAesGcm_t; + +# ifdef USE_ROT_AES_BLOCK +typedef struct +{ + ValSymContextPtr_t ctx; +} psAesKey_t; +# endif + +# ifdef USE_ROT_AES_CBC +typedef struct +{ + ValSymContextPtr_t ctx; +} psAesCbc_t; +# endif + +# endif /* USE_ROT_AES_GCM */ + /******************************************************************************/ # ifdef USE_MATRIX_3DES diff --git a/crypto/test/Makefile b/crypto/test/Makefile index 1755760..39b9b21 100644 --- a/crypto/test/Makefile +++ b/crypto/test/Makefile @@ -41,6 +41,7 @@ include $(MATRIXSSL_ROOT)/common.mk # Linked files STATICS:=../libcrypt_s.a $(MATRIXSSL_ROOT)/core/libcore_s.a +STATICS+=$(LIBDRIVER_VAL_UP_PATH) all: compile diff --git a/crypto/test/algorithmTest.c b/crypto/test/algorithmTest.c index 1b092ea..ec436f9 100644 --- a/crypto/test/algorithmTest.c +++ b/crypto/test/algorithmTest.c @@ -891,6 +891,7 @@ static int32 psAesTestBlock(void) return 0; } +# ifdef USE_AES_CBC /* Known vector test - AES-CBC */ @@ -988,6 +989,7 @@ static int32 psAesTestCBC(void) } return 0; } +# endif /* USE_AES_CBC */ # ifdef USE_AES_GCM int32 psAesTestGCM2(void) @@ -4145,6 +4147,7 @@ static int32 psRsaSignTest(void) return psRsaSignE3Test(); } +# if defined(USE_RSA) && defined(USE_PEM_DECODE) static int32 psRsaKeyFormatTests(void) { unsigned char tbs[] = { 'm', 'y', 't', 'b', 's' }; @@ -4278,8 +4281,10 @@ static int32 psRsaKeyFormatTests(void) } if (Memcmp(sig1, expectedSig1, sigLen1)) { +# ifdef DEBUG_ALGORITHM_TEST psTraceBytes("Got: ", sig1, sigLen1); psTraceBytes("Expected: ", expectedSig1, sigLen1); +# endif _psTrace("psSign output sig1 is wrong\n"); goto out_fail; } @@ -4305,8 +4310,10 @@ static int32 psRsaKeyFormatTests(void) } if (Memcmp(sig2, expectedSig2, sigLen2)) { +#ifdef DEBUG_ALGORITHM_TEST psTraceBytes("Got: ", sig2, sigLen2); psTraceBytes("Expected: ", expectedSig2, sigLen2); +#endif _psTrace("psSign output sig2 is wrong\n"); goto out_fail; } @@ -4388,6 +4395,7 @@ out_fail: psFree(sig2, NULL); return PS_FAILURE; } +# endif /* USE_RSA && USE_PEM_DECODE */ # endif /* USE_PRIVATE_KEY_PARSING */ /******************************************************************************/ @@ -4648,6 +4656,7 @@ LBL_ERR: /******************************************************************************/ # ifdef USE_PKCS1_PSS # ifndef USE_CL_RSA /* crypto-cl doesn't support the used API. */ +# ifdef USE_SHA1 /* Test uses SHA-1. */ /* PSS-VEC.TXT from RSA PKCS#1 web page */ static unsigned char key2N[] = { 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51, 0x87, 0xdc, @@ -4766,6 +4775,10 @@ static unsigned char key2sig[] = { static int32 psRsaPssVectorTest(void) { +# ifdef USE_ROT_RSA + _psTrace("SKIPPED\n"); + return PS_SUCCESS; +# else psPool_t *pool = NULL; psRsaKey_t key1; pstm_int mpN, mpe, mpd, mpp, mpq, mpdP, mpdQ, mpqP; @@ -4905,7 +4918,9 @@ LBL_ERR: psFree(outPss, pool); psFree(outRsaE, pool); return ret; +# endif /* USE_ROT_RSA */ } +# endif /* USE_SHA1 */ # endif /* USE_CL_RSA */ # endif /* USE_PKCS1_PSS */ @@ -6372,8 +6387,10 @@ static int32_t psEccPairwiseTest(void) if (memcmpct(sk1k2, sk2k1, curve->size) != 0) { _psTrace("Shared secret doesn't match."); +#ifdef DEBUG_ALGORITHM_TEST psTraceBytes("K1K2 Secret", sk1k2, secretlen); psTraceBytes("K2K1 Secret", sk2k1, secretlen); +#endif goto L_FAIL; } _psTrace(" PASSED\n"); @@ -7062,7 +7079,7 @@ static int32 psEd25519Test(void) sizeof(myPrivKeyBuf2), NULL, &myPrivKey); - FAIL_IF(rc != 3); + FAIL_IF(rc != PS_ED25519); FAIL_IF(myPrivKey.type != PS_ED25519); _psTrace(" PASSED\n"); @@ -7295,7 +7312,7 @@ static test_t tests[] = { #endif , "***** RSA RSAES_OAEP TESTS *****" }, -#if defined(USE_PKCS1_PSS) && !defined(USE_CL_RSA) && !defined(USE_HARDWARE_CRYPTO_PKA) +#if defined(USE_PKCS1_PSS) && defined(USE_SHA1) && !defined(USE_CL_RSA) && !defined(USE_HARDWARE_CRYPTO_PKA) { psRsaPssVectorTest #else { NULL diff --git a/crypto/test/eccperf/Makefile b/crypto/test/eccperf/Makefile index ff1364a..5339797 100644 --- a/crypto/test/eccperf/Makefile +++ b/crypto/test/eccperf/Makefile @@ -18,6 +18,10 @@ STATIC:=\ $(MATRIXSSL_ROOT)/crypto/libcrypt_s.a \ $(MATRIXSSL_ROOT)/core/libcore_s.a +#ifdef USE_ROT_CRYPTO +STATIC+=$(LIBDRIVER_VAL_UP_PATH) +#endif + all: compile compile: $(OBJS) $(TEST_EXE) diff --git a/crypto/test/rsaperf/Makefile b/crypto/test/rsaperf/Makefile index b34fb47..fe77684 100644 --- a/crypto/test/rsaperf/Makefile +++ b/crypto/test/rsaperf/Makefile @@ -18,6 +18,10 @@ STATIC:=\ $(MATRIXSSL_ROOT)/crypto/libcrypt_s.a \ $(MATRIXSSL_ROOT)/core/libcore_s.a +#ifdef USE_ROT_CRYPTO +STATIC+=$(LIBDRIVER_VAL_UP_PATH) +#endif + all: compile compile: $(OBJS) $(TEST_EXE) diff --git a/crypto/test/throughputTest.c b/crypto/test/throughputTest.c index 0b66f65..d2a5f95 100644 --- a/crypto/test/throughputTest.c +++ b/crypto/test/throughputTest.c @@ -52,6 +52,7 @@ #define LARGE_CHUNKS 4096 #define HUGE_CHUNKS 16 * 1024 +# ifdef USE_AES_CBC static unsigned char iv[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; @@ -59,6 +60,7 @@ static unsigned char key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; +# endif enum { @@ -81,7 +83,7 @@ enum CHACHA20POLY1305IETF_ALG }; -#if defined(USE_HMAC_SHA1) || defined(USE_HMAC_SHA256) +#if defined(USE_AES_CBC) && (defined(USE_HMAC_SHA1) || defined(USE_HMAC_SHA256)) static void runWithHmac(psCipherContext_t *ctx, psHmac_t *hmac, int32 hashSize, int32 chunk, int32 alg) { @@ -118,7 +120,9 @@ static void runWithHmac(psCipherContext_t *ctx, psHmac_t *hmac, # else psHmacSha1Update(&hmac->u.sha1, dataChunk, chunk); # endif +# ifdef USE_AES_CBC psAesEncryptCBC(&ctx->aes, dataChunk, dataChunk, chunk); +# endif bytesSent += chunk; } psHmacSha1Final(&hmac->u.sha1, mac); @@ -138,7 +142,9 @@ static void runWithHmac(psCipherContext_t *ctx, psHmac_t *hmac, # else psHmacSha256Update(&hmac->u.sha256, dataChunk, chunk); # endif +# ifdef USE_AES_CBC psAesEncryptCBC(&ctx->aes, dataChunk, dataChunk, chunk); +# endif bytesSent += chunk; } psHmacSha256Final(&hmac->u.sha256, mac); @@ -166,8 +172,9 @@ static void runWithHmac(psCipherContext_t *ctx, psHmac_t *hmac, # endif psFree(dataChunk, NULL); } -#endif /* USE_HMAC */ +#endif /* USE_AES_CBC && USE_HMAC */ +# ifdef USE_AES_CBC static void runTime(psCipherContext_t *ctx, psCipherGivContext_t *ctx_giv, int32 chunk, int32 alg) { @@ -320,6 +327,7 @@ static void runTime(psCipherContext_t *ctx, psCipherGivContext_t *ctx_giv, #endif } +# endif /* USE_AES_CBC */ /******************************************************************************/ #ifdef USE_AES_CBC @@ -636,6 +644,8 @@ void runDigestTime(psDigestContext_t *ctx, int32 chunk, int32 alg) int32 diffm; #endif + (void)rv; + dataChunk = psMalloc(NULL, chunk); bytesToSend = (DATABYTES_AMOUNT / chunk) * chunk; bytesSent = 0; @@ -644,68 +654,68 @@ void runDigestTime(psDigestContext_t *ctx, int32 chunk, int32 alg) { #ifdef USE_SHA1 case SHA1_ALG: - psSha1Init(&ctx->sha1); + psSha1Init(&ctx->u.sha1); psGetTime(&start, NULL); while (bytesSent < bytesToSend) { - psSha1Update(&ctx->sha1, dataChunk, chunk); + psSha1Update(&ctx->u.sha1, dataChunk, chunk); bytesSent += chunk; } - psSha1Final(&ctx->sha1, hashout); + psSha1Final(&ctx->u.sha1, hashout); psGetTime(&end, NULL); break; #endif #ifdef USE_SHA256 case SHA256_ALG: - psSha256Init(&ctx->sha256); + psSha256Init(&ctx->u.sha256); psGetTime(&start, NULL); while (bytesSent < bytesToSend) { - psSha256Update(&ctx->sha256, dataChunk, chunk); + psSha256Update(&ctx->u.sha256, dataChunk, chunk); bytesSent += chunk; } - psSha256Final(&ctx->sha256, hashout); + psSha256Final(&ctx->u.sha256, hashout); psGetTime(&end, NULL); break; #endif #ifdef USE_SHA384 case SHA384_ALG: - psSha384Init(&ctx->sha384); + psSha384Init(&ctx->u.sha384); psGetTime(&start, NULL); while (bytesSent < bytesToSend) { - psSha384Update(&ctx->sha384, dataChunk, chunk); + psSha384Update(&ctx->u.sha384, dataChunk, chunk); bytesSent += chunk; } - psSha384Final(&ctx->sha384, hashout); + psSha384Final(&ctx->u.sha384, hashout); psGetTime(&end, NULL); break; #endif #ifdef USE_SHA512 case SHA512_ALG: - psSha512Init(&ctx->sha512); + psSha512Init(&ctx->u.sha512); psGetTime(&start, NULL); while (bytesSent < bytesToSend) { - psSha512Update(&ctx->sha512, dataChunk, chunk); + psSha512Update(&ctx->u.sha512, dataChunk, chunk); bytesSent += chunk; } - psSha512Final(&ctx->sha512, hashout); + psSha512Final(&ctx->u.sha512, hashout); psGetTime(&end, NULL); break; #endif #ifdef USE_MD5 case MD5_ALG: - rv = psMd5Init(&ctx->md5); + rv = psMd5Init(&ctx->u.md5); if (rv != PS_SUCCESS) goto skipped; psGetTime(&start, NULL); while (bytesSent < bytesToSend) { - psMd5Update(&ctx->md5, dataChunk, chunk); + psMd5Update(&ctx->u.md5, dataChunk, chunk); bytesSent += chunk; } - psMd5Final(&ctx->md5, hashout); + psMd5Final(&ctx->u.md5, hashout); psGetTime(&end, NULL); break; #endif @@ -884,7 +894,7 @@ typedef struct } test_t; static test_t tests[] = { -#ifdef USE_AES +#ifdef USE_AES_CBC { psAesTestCBC, "***** AES-CBC TESTS *****" }, # if defined(USE_HMAC_SHA1) || defined(USE_HMAC_SHA256) { psAesTestCBCHmac, "***** AES-CBC + HMAC TESTS *****" }, diff --git a/release_notes-4-0-2-open.html b/doc/CHANGES_v4.x.html similarity index 83% rename from release_notes-4-0-2-open.html rename to doc/CHANGES_v4.x.html index b705363..783b17c 100644 --- a/release_notes-4-0-2-open.html +++ b/doc/CHANGES_v4.x.html @@ -9,6 +9,24 @@

MatrixSSL 4.x changelog

+

Changes between 4.0.2 and 4.1.0 [April 2019]

+
    +
  • TLS:

    +
      +
    • (RoT Edition only): Added support for Inside Secure VaultIP (Root-of-Trust) crypto provider.

    • +
    • Improved the separation of private and public TLS header files for better private-public separation. The public headers now of the form matrixsslApi*.h, while private headers are of the form matrixssllib_*.h.

    • +
    • Added client-side support for X25519 in TLS 1.2.

    • +
    • Added client-side support for RSASSA-PSS signatures in TLS 1.2.

    • +
    • Added support for RSASSA-PSS key/cert pairs.

    • +
    • Fix vulnerabilities reported by Robert Święcki (discovered using Hongfuzzer): a server-side heap buffer read overflow when parsing maliciously crafted ClientHello extensions and a segfault in TLS 1.2 GCM decryption of maliciously crafted records with small ciphertext.

    • +
    • Added the simpleClient.c and simpleServer.c example applications. These are intended as minimalistic examples of how to use the top-level TLS API.

    • +
    • Fixed bugs in matrixSslSessOptsServerTlsVersionRange and matrixSslSessOptsClientTlsVersionRange.

    • +
    • Fixed bug that caused non-insitu app data encryption to fail in tls13EncodeAppData when using the matrixSslEncodeToOutdata API instead of the more standard matrixSslGetWriteBuf + matrixSslEncodeWritebuf pattern.

    • +
    • Added new minimal example configurations: tls12-minimal, tls12-minimal-client-ecc, tls13-minimal, tls13-minimal-client-ecc

    • +
    • When performing TLS 1.2 renegotiation, re-send the original ClientHello cipher list.

    • +
    • Added the USE_LENIENT_TLS_RECORD_VERSION_MATCHING compatibility option.

    • +
  • +

Changes between 4.0.1 and 4.0.2 [February 2019]

This version fixes a critical vulnerability in RSA signature verification. A maliciously crafted certificate can be used to trigger a stack buffer overflow, allowing potential remote code execution attacks. The vulnerability only affects version 4.0.1 and the standard Matrix Crypto provider. Other providers, such as the FIPS crypto provider, are not affected by the bug. Thanks to Tavis Ormandy for reporting this.

Changes between 4.0.0 and 4.0.1 [November 2018]

diff --git a/doc/CHANGES_v4.0.md b/doc/CHANGES_v4.x.md similarity index 78% rename from doc/CHANGES_v4.0.md rename to doc/CHANGES_v4.x.md index b62b68a..0760c8c 100644 --- a/doc/CHANGES_v4.0.md +++ b/doc/CHANGES_v4.x.md @@ -1,5 +1,61 @@ # MatrixSSL 4.x changelog +## Changes between 4.0.2 and 4.1.0 [April 2019] + +- TLS: + + * (RoT Edition only): Added support for Inside Secure VaultIP + (Root-of-Trust) crypto provider. + + * Improved the separation of private and public TLS header files + for better private-public separation. The public headers now of + the form matrixsslApi\*.h, while private headers are of the form + matrixssllib\_*.h. + + * Added client-side support for X25519 in TLS 1.2. + + * Added client-side support for RSASSA-PSS signatures in TLS 1.2. + + * Added support for RSASSA-PSS key/cert pairs. + + * Fix vulnerabilities reported by Robert Święcki (discovered using + Hongfuzzer): a server-side heap buffer read overflow when + parsing maliciously crafted ClientHello extensions and a + segfault in TLS 1.2 GCM decryption of maliciously crafted + records with small ciphertext. + + * Added the simpleClient.c and simpleServer.c example + applications. These are intended as minimalistic examples of how + to use the top-level TLS API. + + * Fixed bugs in matrixSslSessOptsServerTlsVersionRange and + matrixSslSessOptsClientTlsVersionRange. + + * Fixed bug that caused non-insitu app data encryption to fail in + tls13EncodeAppData when using the matrixSslEncodeToOutdata API + instead of the more standard matrixSslGetWriteBuf + + matrixSslEncodeWritebuf pattern. + + * Added new minimal example configurations: tls12-minimal, + tls12-minimal-client-ecc, tls13-minimal, + tls13-minimal-client-ecc + + * When performing TLS 1.2 renegotiation, re-send the original + ClientHello cipher list. + + * Added the USE_LENIENT_TLS_RECORD_VERSION_MATCHING compatibility + option. + +## Changes between 4.0.1 and 4.0.2 [February 2019] + +This version fixes a critical vulnerability in RSA signature +verification. A maliciously crafted certificate can be used to trigger +a stack buffer overflow, allowing potential remote code execution +attacks. The vulnerability only affects version 4.0.1 and the standard +Matrix Crypto provider. Other providers, such as the FIPS crypto +provider, are not affected by the bug. Thanks to Tavis Ormandy for +reporting this. + ## Changes between 4.0.0 and 4.0.1 [November 2018] This version improves the security of RSA PKCS #1.5 signature diff --git a/doc/CHANGES_v4.0.txt b/doc/CHANGES_v4.x.txt similarity index 78% rename from doc/CHANGES_v4.0.txt rename to doc/CHANGES_v4.x.txt index 69936c7..afac54e 100644 --- a/doc/CHANGES_v4.0.txt +++ b/doc/CHANGES_v4.x.txt @@ -3,6 +3,63 @@ MATRIXSSL 4.X CHANGELOG +Changes between 4.0.2 and 4.1.0 [April 2019] + +- TLS: + + - (RoT Edition only): Added support for Inside Secure + VaultIP (Root-of-Trust) crypto provider. + + - Improved the separation of private and public TLS header files + for better private-public separation. The public headers now of + the form matrixsslApi*.h, while private headers are of the + form matrixssllib_*.h. + + - Added client-side support for X25519 in TLS 1.2. + + - Added client-side support for RSASSA-PSS signatures in TLS 1.2. + + - Added support for RSASSA-PSS key/cert pairs. + + - Fix vulnerabilities reported by Robert Święcki (discovered using + Hongfuzzer): a server-side heap buffer read overflow when + parsing maliciously crafted ClientHello extensions and a + segfault in TLS 1.2 GCM decryption of maliciously crafted + records with small ciphertext. + + - Added the simpleClient.c and simpleServer.c + example applications. These are intended as minimalistic + examples of how to use the top-level TLS API. + + - Fixed bugs in matrixSslSessOptsServerTlsVersionRange + and matrixSslSessOptsClientTlsVersionRange. + + - Fixed bug that caused non-insitu app data encryption to fail in + tls13EncodeAppData when using the matrixSslEncodeToOutdata API + instead of the more standard matrixSslGetWriteBuf + + matrixSslEncodeWritebuf pattern. + + - Added new minimal example configurations: tls12-minimal, + tls12-minimal-client-ecc, tls13-minimal, + tls13-minimal-client-ecc + + - When performing TLS 1.2 renegotiation, re-send the original + ClientHello cipher list. + + - Added the USE_LENIENT_TLS_RECORD_VERSION_MATCHING + compatibility option. + + +Changes between 4.0.1 and 4.0.2 [February 2019] + +This version fixes a critical vulnerability in RSA signature +verification. A maliciously crafted certificate can be used to trigger a +stack buffer overflow, allowing potential remote code execution attacks. +The vulnerability only affects version 4.0.1 and the standard Matrix +Crypto provider. Other providers, such as the FIPS crypto provider, are +not affected by the bug. Thanks to Tavis Ormandy for reporting this. + + Changes between 4.0.0 and 4.0.1 [November 2018] This version improves the security of RSA PKCS #1.5 signature diff --git a/doc/MatrixCMS_API.pdf b/doc/MatrixCMS_API.pdf index 266c121..02bcf27 100644 Binary files a/doc/MatrixCMS_API.pdf and b/doc/MatrixCMS_API.pdf differ diff --git a/doc/MatrixDTLS_DeveloperGuide.pdf b/doc/MatrixDTLS_DeveloperGuide.pdf index 6646f79..e80bf99 100644 Binary files a/doc/MatrixDTLS_DeveloperGuide.pdf and b/doc/MatrixDTLS_DeveloperGuide.pdf differ diff --git a/doc/MatrixKeyAndCertGeneration.pdf b/doc/MatrixKeyAndCertGeneration.pdf index d13513e..4436e4c 100644 Binary files a/doc/MatrixKeyAndCertGeneration.pdf and b/doc/MatrixKeyAndCertGeneration.pdf differ diff --git a/doc/MatrixSSL_API.pdf b/doc/MatrixSSL_API.pdf index ef5ff6e..db76286 100644 Binary files a/doc/MatrixSSL_API.pdf and b/doc/MatrixSSL_API.pdf differ diff --git a/doc/MatrixSSL_CertificatesAndCRLs.pdf b/doc/MatrixSSL_CertificatesAndCRLs.pdf index ffe217f..9de307d 100644 Binary files a/doc/MatrixSSL_CertificatesAndCRLs.pdf and b/doc/MatrixSSL_CertificatesAndCRLs.pdf differ diff --git a/doc/MatrixSSL_DiffieHellman.pdf b/doc/MatrixSSL_DiffieHellman.pdf index 097049f..1456b1e 100644 Binary files a/doc/MatrixSSL_DiffieHellman.pdf and b/doc/MatrixSSL_DiffieHellman.pdf differ diff --git a/doc/MatrixSSL_EllipticCurveCiphers.pdf b/doc/MatrixSSL_EllipticCurveCiphers.pdf index 5f36685..93a75f7 100644 Binary files a/doc/MatrixSSL_EllipticCurveCiphers.pdf and b/doc/MatrixSSL_EllipticCurveCiphers.pdf differ diff --git a/doc/MatrixSSL_ExternalModuleIntegration.pdf b/doc/MatrixSSL_ExternalModuleIntegration.pdf index ba1a6dc..2ddb16c 100644 Binary files a/doc/MatrixSSL_ExternalModuleIntegration.pdf and b/doc/MatrixSSL_ExternalModuleIntegration.pdf differ diff --git a/doc/MatrixSSL_GettingStarted.pdf b/doc/MatrixSSL_GettingStarted.pdf index 5d3f7dd..c5e8b98 100644 Binary files a/doc/MatrixSSL_GettingStarted.pdf and b/doc/MatrixSSL_GettingStarted.pdf differ diff --git a/doc/MatrixSSL_PortingGuide.pdf b/doc/MatrixSSL_PortingGuide.pdf index 9d5dad0..649077b 100644 Binary files a/doc/MatrixSSL_PortingGuide.pdf and b/doc/MatrixSSL_PortingGuide.pdf differ diff --git a/doc/MatrixSSL_PreSharedKeys.pdf b/doc/MatrixSSL_PreSharedKeys.pdf index 0689ce6..41913b7 100644 Binary files a/doc/MatrixSSL_PreSharedKeys.pdf and b/doc/MatrixSSL_PreSharedKeys.pdf differ diff --git a/matrixssl/Makefile b/matrixssl/Makefile index 76fa90f..113640f 100644 --- a/matrixssl/Makefile +++ b/matrixssl/Makefile @@ -15,6 +15,7 @@ SRC:=\ extDecode.c \ hsDecode.c \ hsHash.c \ + hsHashBuffered.c \ hsNegotiateVersion.c \ matrixssl.c \ matrixsslKeys.c \ @@ -42,6 +43,7 @@ SRC:=\ tls13Resume.c \ tls13SigVer.c \ tls13TrHash.c \ + tls13TrHashBuffered.c \ sslv3.c \ tls.c diff --git a/matrixssl/cipherSuite.c b/matrixssl/cipherSuite.c index 382c90f..d96312b 100644 --- a/matrixssl/cipherSuite.c +++ b/matrixssl/cipherSuite.c @@ -260,6 +260,16 @@ int32 csAesGcmDecrypt(void *ssl, unsigned char *ct, unsigned char nonce[12]; unsigned char aad[TLS_GCM_AAD_LEN]; + /* + Minimum GCM ciphertext length in TLS 1.2: + 25 = 1 + 16 (tag) + 8 (nonce_explicit). + */ + if (len < 25) + { + psTraceErrr("Invalid GCM ciphertext length\n"); + psTraceIntInfo("(%u)\n", len); + return PS_FAILURE; + } ctx = &lssl->sec.decryptCtx.aesgcm; seqNotDone = 1; @@ -2780,6 +2790,7 @@ int32 chooseCipherSuite(ssl_t *ssl, unsigned char *listStart, int32 listLen) #ifndef USE_ONLY_PSK_CIPHER_SUITE # ifdef USE_ECC_CIPHER_SUITE + /* See if any of the EC suites are supported. Needed by client very early on to know whether or not to add the EC client hello extensions @@ -2791,35 +2802,91 @@ int32_t eccSuitesSupported(const ssl_t *ssl, if (cipherSpecLen == 0) { - if (sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA) || - sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) || - sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA) || - sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA) || - sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA) || -# ifdef USE_TLS_1_2 - sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384) || - sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) || - sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) || -# endif - sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA)) + if (0 +#ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA) +#endif +#ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA) +#endif +#ifdef USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) +#endif +#ifdef USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) +#endif +#ifdef USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) +#endif +#ifdef USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA) +#endif +#ifdef USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA) +#endif +#ifdef USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA) +#endif +#ifdef USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + || sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA) +#endif +#ifdef USE_TLS_1_2 +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384) +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256) +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384) +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256) +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384) +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256) +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384) +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256) +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + || sslGetCipherSpec(ssl, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384) +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + || sslGetCipherSpec(ssl, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) +# endif +# endif /* USE_TLS_1_2 */ + ) { return 1; } @@ -2828,35 +2895,91 @@ int32_t eccSuitesSupported(const ssl_t *ssl, { while (i < cipherSpecLen) { - if (cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA || - cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA || - cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA || - cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA || - cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_256_CBC_SHA || -# ifdef USE_TLS_1_2 - cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 || - cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 || - cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 || - cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 || - cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 || - cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 || - cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 || - cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 || - cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 || - cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 || - cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 || - cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 || - cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 || - cipherSpecs[i] == TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 || -# endif - cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_128_CBC_SHA) + if (0 +#ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + || cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA +#endif +#ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + || cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA +#endif +#ifdef USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA +#endif +#ifdef USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA +#endif +#ifdef USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA +#endif +#ifdef USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + || cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA +#endif +#ifdef USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + || cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA +#endif +#ifdef USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + || cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_256_CBC_SHA +#endif +#ifdef USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + || cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_128_CBC_SHA +#endif +#ifdef USE_TLS_1_2 +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + || cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + || cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + || cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + || cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + || cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 +# endif +# ifdef USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + || cipherSpecs[i] == TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + || cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + || cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + || cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + || cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + || cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 +# endif +# ifdef USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + || cipherSpecs[i] == TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 +# endif +# ifdef USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + || cipherSpecs[i] == TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 +# endif +# ifdef USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + || cipherSpecs[i] == TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 +# endif +#endif /* USE_TLS_1_2 */ + ) { return 1; } @@ -3037,7 +3160,6 @@ const sslCipherSpec_t *sslGetCipherSpec(const ssl_t *ssl, uint16_t id) return NULL; } #endif - #ifdef USE_SEC_CONFIG if (!ciphersuiteAllowedBySecConfig(ssl, id)) { @@ -3106,7 +3228,7 @@ const sslCipherSpec_t *sslGetCipherSpec(const ssl_t *ssl, uint16_t id) } /* The server should reject TLS 1.3 cipher suites if TLS 1.3 is not enabled. */ - if (IS_SERVER(ssl) && !SUPP_VER(ssl, v_tls_1_3_any)) + if (MATRIX_IS_SERVER(ssl) && !SUPP_VER(ssl, v_tls_1_3_any)) { if (supportedCiphers[i].type == CS_TLS13) { @@ -3210,13 +3332,15 @@ int32_t sslGetCipherSpecListExt(const ssl_t *ssl, unsigned short i; int32 ignored; + p = c; /* assigned always to silence gcc 4.7 */ + end = c + len; + if (encodeList) { if (len < 4) { return -1; } - end = c + len; p = c; c += 2; } diff --git a/matrixssl/dtls.c b/matrixssl/dtls.c index 9abcc6e..a68dbe5 100644 --- a/matrixssl/dtls.c +++ b/matrixssl/dtls.c @@ -553,7 +553,7 @@ int32 dtlsEncryptFragRecord(ssl_t *ssl, flightEncode_t *msg, if (ssl->encrypt(ssl, encryptStart, encryptStart, (int32) (*c - encryptStart)) < 0) { - psTraceInfo("Error encrypting message for write\n"); + psTraceErrr("Error encrypting message for write\n"); return PS_FAILURE; } @@ -664,7 +664,7 @@ int32 dtlsChkReplayWindow(ssl_t *ssl, unsigned char *seq64) ssl->dtlsBitmap = 0; return 1; /* initial one */ } - if (dtlsCompareEpoch(ssl->rec.epoch, ssl->resendEpoch) == 1 && + if (dtlsCompareEpoch(ssl->rec.epoch, ssl->expectedEpoch) >= 0 && lastSeq > 0) { ssl->dtlsBitmap = 0; @@ -856,7 +856,8 @@ static int32 dtlsRevertWriteCipher(ssl_t *ssl) ssl->nativeEnMacSize = ssl->oenNativeHmacSize; ssl->enIvSize = ssl->oenIvSize; ssl->enBlockSize = ssl->oenBlockSize; - Memcpy(ssl->sec.writeIV, ssl->owriteIV, ssl->oenIvSize); + Memcpy(ssl->sec.writeIV, ssl->owriteIV, sizeof(ssl->owriteIV)); + Memcpy(ssl->sec.writeKey, ssl->owriteKey, sizeof(ssl->owriteKey)); # ifdef USE_NATIVE_TLS_ALGS Memcpy(ssl->sec.writeMAC, ssl->owriteMAC, ssl->oenMacSize); Memcpy(&ssl->sec.encryptCtx, &ssl->oencryptCtx, @@ -1036,6 +1037,78 @@ static int32 dtlsGetNextRecordLen(ssl_t *ssl, int32 pmtu, sslBuf_t *out, } /******************************************************************************/ + +static bool canResend(ssl_t *ssl) +{ + bool canSend = false; + + if (ssl->flags & SSL_FLAGS_SERVER) + { + if (ssl->hsState == SSL_HS_FINISHED) + canSend = 1; + + if (ssl->hsState == SSL_HS_CLIENT_HELLO) + { + canSend = 1; /* any handshake type */ + } + if (!(ssl->flags & SSL_FLAGS_RESUMED)) + { + if (ssl->hsState == SSL_HS_DONE) + { + canSend = 1; /* DONE set on parse of peer FINISHED */ + } + } + + /* Different client auth boundary for second flight */ + if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) + { + if (ssl->hsState == SSL_HS_CERTIFICATE) + { + canSend = 1; + } + } + else + { + if (ssl->hsState == SSL_HS_CLIENT_KEY_EXCHANGE) + { + canSend = 1; + } + } + + if (ssl->flags & SSL_FLAGS_RESUMED) + { + if (ssl->hsState == SSL_HS_FINISHED) + { + canSend = 1; + } + } + } + else + { +#if 0 + /* Client tests */ + if (ssl->hsState == SSL_HS_SERVER_HELLO) + { + canSend = 1; + } + if (!(ssl->flags & SSL_FLAGS_RESUMED)) + { + if (ssl->hsState == SSL_HS_FINISHED) + { + canSend = 1; + } + } + if (ssl->hsState == SSL_HS_DONE) + { + canSend = 1; /* Done is set on parse of peer FINISHED */ + } +#else + canSend = 1; /* Why wouldnt't it be safe to resend aways when in doubt */ +#endif + } + return canSend; +} + /* Manages the DTLS flight buffer to make sure each call will return data that is less than the PMTU (dtlsGetNextRecordLen). Also, plays a role @@ -1080,7 +1153,7 @@ int32 matrixDtlsGetOutdata(ssl_t *ssl, unsigned char **buf) 0 and flag the flight as needing a resend for the cases in which we come back in here with a zero buffer (a timeout happen and resend needed) */ - if ((tmp.end == tmp.start) && (ssl->flightDone == 1)) + if (ssl->outlen == 0 && ssl->flightDone == 1) { ssl->flightDone = 0; *buf = NULL; @@ -1090,7 +1163,7 @@ int32 matrixDtlsGetOutdata(ssl_t *ssl, unsigned char **buf) /* If ssl->outbuf is empty and not in appDataExch mode this is a flight resend */ - if ((tmp.end == tmp.start) && (ssl->appDataExch == 0)) + if (ssl->outlen == 0 && ssl->appDataExch == 0) { /* And now the ugly part. If we have been receiving records that @@ -1105,71 +1178,7 @@ int32 matrixDtlsGetOutdata(ssl_t *ssl, unsigned char **buf) The state is always the handshake message you expect to be receiving from the peer. */ - safeToResend = 0; - - if (ssl->flags & SSL_FLAGS_SERVER) - { - if (ssl->hsState == SSL_HS_CLIENT_HELLO) - { - safeToResend = 1; /* any handshake type */ - } - if (!(ssl->flags & SSL_FLAGS_RESUMED)) - { - if (ssl->hsState == SSL_HS_DONE) - { - safeToResend = 1; /* DONE set on parse of peer FINISHED */ - } - } - -# ifdef USE_CLIENT_AUTH - /* Different client auth boundary for second flight */ - if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) - { - if (ssl->hsState == SSL_HS_CERTIFICATE) - { - safeToResend = 1; - } - } - else - { -# endif /* USE_CLIENT_AUTH */ - if (ssl->hsState == SSL_HS_CLIENT_KEY_EXCHANGE) - { - safeToResend = 1; - } -# ifdef USE_CLIENT_AUTH - } -# endif /* USE_CLIENT_AUTH */ - - if (ssl->flags & SSL_FLAGS_RESUMED) - { - if (ssl->hsState == SSL_HS_FINISHED) - { - safeToResend = 1; - } - } - - } - else - { - /* Client tests */ - if (ssl->hsState == SSL_HS_SERVER_HELLO) - { - safeToResend = 1; - } - if (!(ssl->flags & SSL_FLAGS_RESUMED)) - { - if (ssl->hsState == SSL_HS_FINISHED) - { - safeToResend = 1; - } - } - if (ssl->hsState == SSL_HS_DONE) - { - safeToResend = 1; /* Done is set on parse of peer FINISHED */ - } - - } + safeToResend = canResend(ssl); if (safeToResend == 0) { @@ -1221,10 +1230,9 @@ int32 matrixDtlsSentData(ssl_t *ssl, uint32 bytes) { int32 rc; + /* tis decrements bytes from length of constructed output */ rc = matrixSslSentData(ssl, bytes); -/* - NOTE: appDataExch only gets set on the receipt of an application data - */ + if (ssl->outlen == 0 && ssl->appDataExch == 0) { ssl->flightDone = 1; diff --git a/matrixssl/extDecode.c b/matrixssl/extDecode.c index be4e7a6..08b6e68 100644 --- a/matrixssl/extDecode.c +++ b/matrixssl/extDecode.c @@ -209,6 +209,12 @@ int32 parseClientHelloExtensions(ssl_t *ssl, unsigned char **cp, unsigned short # endif while (c != end) { + if (end - c < 2) + { + ssl->err = SSL_ALERT_DECODE_ERROR; + psTraceErrr("Invalid extension header len\n"); + return MATRIXSSL_ERROR; + } extType = *c << 8; c++; /* Individual hello ext */ extType += *c; c++; if (end - c < 2) diff --git a/matrixssl/hsDecode.c b/matrixssl/hsDecode.c index 0f39fc3..8fd6cef 100644 --- a/matrixssl/hsDecode.c +++ b/matrixssl/hsDecode.c @@ -563,47 +563,22 @@ int32 parseClientHello(ssl_t *ssl, unsigned char **cp, unsigned char *end) else { ssl->flags &= ~SSL_FLAGS_RESUMED; +# ifdef USE_MATRIXSSL_STATS + matrixsslUpdateStat(ssl, FAILED_RESUMPTIONS_STAT, 1); +# endif + + /* + Failed to resume (both via Session ID and ticket). + + Clear the Session ID, unless we are using TLS 1.3, + in which case we MUST echo the client's Session ID. + */ if (!NGTD_VER(ssl, v_tls_1_3_any)) { -# ifdef USE_STATELESS_SESSION_TICKETS - /* - Client MAY generate and include a Session ID in the - TLS ClientHello. If the server accepts the ticket - and the Session ID is not empty, then it MUST respond - with the same Session ID present in the ClientHello. Check - if client is even using the mechanism though. - - In TLS 1.3, the server MUST echo the client's Session ID - back, but otherwise ignore it. Make sure we don't clear it. - */ - if (ssl->sid) - { - if (ssl->sid->sessionTicketState == SESS_TICKET_STATE_INIT) - { - Memset(ssl->sessionId, 0, SSL_MAX_SESSION_ID_SIZE); - ssl->sessionIdLen = 0; - } - else - { - /* This flag means we received a session we can't resume - but we have to send it back if we also get a ticket - later that we like */ - ssl->extFlags.session_id = 1; - } - } - else - { - Memset(ssl->sessionId, 0, SSL_MAX_SESSION_ID_SIZE); - ssl->sessionIdLen = 0; - } -# else Memset(ssl->sessionId, 0, SSL_MAX_SESSION_ID_SIZE); ssl->sessionIdLen = 0; -# ifdef USE_MATRIXSSL_STATS - matrixsslUpdateStat(ssl, FAILED_RESUMPTIONS_STAT, 1); -# endif -# endif - } /* !NGTD_VER(ssl, v_tls_1_3_any) */ + } + } } @@ -955,6 +930,9 @@ int32 parseClientKeyExchange(ssl_t *ssl, int32 hsLen, unsigned char **cp, { return SSL_MEM_ERROR; } +# ifdef USE_ROT_ECC + ssl->sec.eccKeyPub->rotKeyType = ps_ecc_key_type_ecdhe; +# endif if (psEccX963ImportKey(ssl->hsPool, c, pubKeyLen, ssl->sec.eccKeyPub, ssl->sec.eccKeyPriv->curve) < 0) { @@ -1147,6 +1125,9 @@ int32 parseClientKeyExchange(ssl_t *ssl, int32 hsLen, unsigned char **cp, { return SSL_MEM_ERROR; } +# ifdef USE_ROT_ECC + ssl->sec.eccKeyPub->rotKeyType = ps_ecc_key_type_ecdhe; +# endif if (psEccX963ImportKey(ssl->hsPool, c, pubKeyLen, ssl->sec.eccKeyPub, ecc->curve) < 0) { @@ -1368,78 +1349,134 @@ int32 parseClientKeyExchange(ssl_t *ssl, int32 hsLen, unsigned char **cp, # ifndef USE_ONLY_PSK_CIPHER_SUITE # ifdef USE_CLIENT_AUTH int32 parseCertificateVerify(ssl_t *ssl, - unsigned char hsMsgHash[SHA512_HASH_SIZE], - unsigned char **cp, unsigned char *end) + unsigned char hsMsgHash[SHA512_HASH_SIZE], + unsigned char **cp, + unsigned char *end) { - uint32 certVerifyLen, pubKeyLen; - int32 rc, i; - -# ifdef USE_RSA - unsigned char certVerify[SHA512_HASH_SIZE]; -# endif /* USE_RSA */ + uint16_t sigAlg; + unsigned char hashAlg; + uint32_t hashSigAlg; + psSize_t sigLen; + unsigned char *refMsg = hsMsgHash; + psSize_t refMsgLen; + int32 rc; unsigned char *c; - psPool_t *cvpkiPool = NULL; - void *pkiData = ssl->userPtr; + psBool_t verifyResult; + psVerifyOptions_t opts; + psBool_t useEcdsa = PS_FALSE; psTracePrintHsMessageParse(ssl, SSL_HS_CERTIFICATE_VERIFY); c = *cp; rc = 0; PS_VARIABLE_SET_BUT_UNUSED(rc); /* Note: Only used ifdef USE_ECC. */ + Memset(&opts, 0, sizeof(opts)); + if (ssl->sec.cert->pubKeyAlgorithm == OID_ECDSA_KEY_ALG) + { + useEcdsa = PS_TRUE; + } + + /* + TLS 1.2: + + struct { + digitally-signed struct { + opaque handshake_messages[handshake_messages_length]; + } + } CertificateVerify; + + struct { + SignatureAndHashAlgorithm algorithm; + opaque signature<0..2^16-1>; + } DigitallySigned; + + TLS 1.1 and below: + + struct { + Signature signature; + } CertificateVerify; + Where signature is an opaque vector <0..2^16-1> + */ + + /* + In TLS 1.2, we can just parse the signature algorithm ID. + For TLS 1.1 and below, we need to use the defaults: + RSA-MD5-SHA1 or ECDSA-SHA1. + */ + sigAlg = OID_RSA_TLS_SIG_ALG; + refMsgLen = MD5_HASH_SIZE + SHA1_HASH_SIZE; + if (ssl->sec.cert->pubKeyAlgorithm == OID_ECDSA_KEY_ALG) + { + /* + SHA-1 is default for ECDSA. When using TLS 1.1 or below, + hsMsgHash contains the MD5-SHA1 handshake hash. So use the + last 20 bytes from that. + */ + refMsg = hsMsgHash + MD5_HASH_SIZE; + refMsgLen = SHA1_HASH_SIZE; + sigAlg = OID_ECDSA_TLS_SIG_ALG; + } # ifdef USE_TLS_1_2 if (NGTD_VER(ssl, v_tls_with_signature_algorithms)) { - uint32_t hashSigAlg; - if ((uint32) (end - c) < 2) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid Certificate Verify message\n"); + psTraceErrr("Invalid Certificate Verify message 1\n"); return MATRIXSSL_ERROR; } - hashSigAlg = HASH_SIG_MASK(c[0], c[1]); -# ifdef USE_SSL_INFORMATIONAL_TRACE_VERBOSE - psTracePrintSigAlgs(hashSigAlg, "Peer CertificateVerify\n"); -# endif - /* The server-sent algorithms has to be one of the ones we sent in - our ClientHello extension */ + hashAlg = c[0]; + sigAlg = (uint16_t)((c[0] << 8) | c[1]); + /* Convert from official SignatureAndHashAlgorithm ID to MatrixSSL + internal "OID". The "OID" format is expected by psVerifySig. */ + sigAlg = tlsSigAlgToMatrix(sigAlg); + hashSigAlg = HASH_SIG_MASK(c[0], c[1]); + refMsg = hsMsgHash; + + psTracePrintSigAlgs(INDENT_HS_MSG, + "Peer CertificateVerify sig alg", + hashSigAlg, + PS_TRUE); + + if (!useEcdsa) + { + /* TLS 1.2 uses DigestInfos with RSA. */ + opts.msgIsDigestInfo = PS_TRUE; + } + if (!(ssl->hashSigAlg & hashSigAlg)) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid SigHash\n"); + psTraceErrr("Invalid sig alg in parseCertificateVerify\n"); return MATRIXSSL_ERROR; } - switch (c[0]) + /* The SHA-256 handshake hash is passed into this function in the + hsMsgHash buffer. If we need to use a different algorithm, + we retrieve the hash separately. */ + switch (hashAlg) { - - case HASH_SIG_SHA256: - certVerifyLen = SHA256_HASH_SIZE; - break; - -# ifdef USE_SHA384 - case HASH_SIG_SHA384: - /* The one-off grab of SHA-384 handshake hash */ - sslSha384RetrieveHSHash(ssl, hsMsgHash); - certVerifyLen = SHA384_HASH_SIZE; - break; -# endif - -# ifdef USE_SHA512 - case HASH_SIG_SHA512: - /* The one-off grab of SHA-512 handshake hash */ - sslSha512RetrieveHSHash(ssl, hsMsgHash); - certVerifyLen = SHA512_HASH_SIZE; - break; -# endif - # ifdef USE_SHA1 case HASH_SIG_SHA1: - /* The one-off grab of SHA-1 handshake hash */ sslSha1RetrieveHSHash(ssl, hsMsgHash); - certVerifyLen = SHA1_HASH_SIZE; + refMsgLen = SHA1_HASH_SIZE; + break; +# endif + case HASH_SIG_SHA256: + refMsgLen = SHA256_HASH_SIZE; + break; +# ifdef USE_SHA384 + case HASH_SIG_SHA384: + sslSha384RetrieveHSHash(ssl, hsMsgHash); + refMsgLen = SHA384_HASH_SIZE; + break; +# endif +# ifdef USE_SHA512 + case HASH_SIG_SHA512: + sslSha512RetrieveHSHash(ssl, hsMsgHash); + refMsgLen = SHA512_HASH_SIZE; break; # endif default: @@ -1447,141 +1484,52 @@ int32 parseCertificateVerify(ssl_t *ssl, psTraceErrr("Invalid Certificate Verify message\n"); return MATRIXSSL_ERROR; } - c += 2; + + c += 2; /* SignatureAndHashAlgorithm parse complete. */ } - else - { - certVerifyLen = MD5_HASH_SIZE + SHA1_HASH_SIZE; - } -# else - certVerifyLen = MD5_HASH_SIZE + SHA1_HASH_SIZE; +# endif /* USE_TLS_1_2 */ + +# ifdef USE_ROT_CRYPTO + /* The crypto-rot implementation of psVerifySig needs the full + TBS reference data, not just the hash. The HS hash is over + ClientHello..ClientKeyExchange. */ + refMsg = ssl->hsMsgBuf.start; + refMsgLen = ssl->hsMsgCHtoCKELen; # endif /* USE_TLS_1_2 */ if ((uint32) (end - c) < 2) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid Certificate Verify message\n"); + psTraceErrr("Invalid Certificate Verify message 2\n"); return MATRIXSSL_ERROR; } - pubKeyLen = *c << 8; c++; - pubKeyLen |= *c; c++; - if ((uint32) (end - c) < pubKeyLen) + sigLen = *c << 8; c++; + sigLen |= *c; c++; + if ((uint32) (end - c) < sigLen) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid Certificate Verify message\n"); + psTraceErrr("Invalid Certificate Verify message 3\n"); return MATRIXSSL_ERROR; } - /* The server side verification of client identity. If we can match - the signature we know the client has possesion of the private key. */ -# ifdef USE_ECC - /* Need to read sig algorithm type out of cert itself */ - if (ssl->sec.cert->pubKeyAlgorithm == OID_ECDSA_KEY_ALG) - { - rc = 0; -# ifdef USE_TLS_1_2 - if (NGTD_VER(ssl, v_tls_with_signature_algorithms)) - { - i = psEccDsaVerify(cvpkiPool, - &ssl->sec.cert->publicKey.key.ecc, - hsMsgHash, certVerifyLen, - c, pubKeyLen, &rc, pkiData); - if (i != PS_SUCCESS) - { - psTraceErrr("ECDSA signature validation failed\n"); - ssl->err = SSL_ALERT_BAD_CERTIFICATE; - return MATRIXSSL_ERROR; - } - } - else - { - certVerifyLen = SHA1_HASH_SIZE; /* per spec */ - i = psEccDsaVerify(cvpkiPool, - &ssl->sec.cert->publicKey.key.ecc, - hsMsgHash + MD5_HASH_SIZE, certVerifyLen, - c, pubKeyLen, - &rc, pkiData); - if (i != PS_SUCCESS) - { - psTraceErrr("ECDSA signature validation failed\n"); - ssl->err = SSL_ALERT_BAD_CERTIFICATE; - return MATRIXSSL_ERROR; - } - } -# else - certVerifyLen = SHA1_HASH_SIZE; /* per spec */ - i = psEccDsaVerify(cvpkiPool, - &ssl->sec.cert->publicKey.key.ecc, - hsMsgHash + MD5_HASH_SIZE, certVerifyLen, - c, pubKeyLen, - &rc, pkiData); - if (i != PS_SUCCESS) - { - psTraceErrr("ECDSA signature validation failed\n"); - ssl->err = SSL_ALERT_BAD_CERTIFICATE; - return MATRIXSSL_ERROR; - } -# endif - if (rc != 1) - { - psTraceErrr("Can't verify certVerify sig\n"); - ssl->err = SSL_ALERT_BAD_CERTIFICATE; - return MATRIXSSL_ERROR; - } - rc = MATRIXSSL_SUCCESS; /* done using rc as a temp */ - } - else + rc = psVerifySig(ssl->hsPool, + refMsg, + refMsgLen, + c, + sigLen, + &ssl->sec.cert->publicKey, + sigAlg, + &verifyResult, + &opts); + if (rc != PS_SUCCESS || verifyResult != PS_TRUE) { -# endif /* USE_ECC */ -# ifdef USE_RSA - -# ifdef USE_TLS_1_2 - if (NGTD_VER(ssl, v_tls_with_pkcs15_auth)) - { - i = pubRsaDecryptSignedElement(cvpkiPool, - &ssl->sec.cert->publicKey.key.rsa, - c, pubKeyLen, certVerify, - certVerifyLen, pkiData); - if (i < 0) - { - psTraceErrr("Unable to decrypt CertVerify digital element\n"); - return MATRIXSSL_ERROR; - } - } - else - { - i = psRsaDecryptPub(cvpkiPool, &ssl->sec.cert->publicKey.key.rsa, c, - pubKeyLen, certVerify, certVerifyLen, pkiData); - if (i < 0) - { - psTraceErrr("Unable to publicly decrypt Certificate Verify message\n"); - return MATRIXSSL_ERROR; - } - } -# else /* !USE_TLS_1_2 */ - i = psRsaDecryptPub(cvpkiPool, &ssl->sec.cert->publicKey.key.rsa, c, - pubKeyLen, certVerify, certVerifyLen, pkiData); - if (i < 0) - { - psTraceErrr("Unable to publicly decrypt Certificate Verify message\n"); + psTraceErrr("CertificateVerify signature validation failed\n"); + psTraceIntInfo("psVerifySig: %d\n", rc); + ssl->err = SSL_ALERT_DECRYPT_ERROR; return MATRIXSSL_ERROR; } -# endif /* USE_TLS_1_2 */ - if (memcmpct(certVerify, hsMsgHash, certVerifyLen) != 0) - { - psTraceErrr("Unable to verify client certificate signature\n"); - return MATRIXSSL_ERROR; - } -# else /* RSA is 'default' so if that didn't get hit there is a problem */ - psTraceErrr("There is no handler for CertificateVerify parse. ERROR\n"); - return MATRIXSSL_ERROR; -# endif /* USE_RSA */ -# ifdef USE_ECC -} -# endif /* USE_ECC*/ - - c += pubKeyLen; + c += sigLen; ssl->hsState = SSL_HS_FINISHED; *cp = c; @@ -1975,7 +1923,9 @@ int32 parseServerKeyExchange(ssl_t *ssl, # ifdef USE_DHE_CIPHER_SUITE int32_t rc, i; +# ifdef REQUIRE_DH_PARAMS uint32 pubDhLen; +# endif # ifndef USE_ONLY_PSK_CIPHER_SUITE unsigned char *sigStart = NULL, *sigStop = NULL; # endif /* USE_ONLY_PSK_CIPHER_SUITE */ @@ -2062,6 +2012,43 @@ int32 parseServerKeyExchange(ssl_t *ssl, /* Next is curveId */ i = *c << 8; c++; i |= *c; c++; + if (!psIsEcdheGroup(i)) + { + ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; + psTraceErrr("Unsupported ECDHE group in SKE\n"); + psTraceIntInfo("Group ID: %d\n", i); + } + ssl->sec.peerCurveId = i; + +# ifdef USE_X25519 + if (i == namedgroup_x25519) + { + /* Next is length octet of opaque point <1..2^8-1>; */ + i = *c; + c++; + if ((end - c < i) || (i != PS_DH_X25519_PUBLIC_KEY_BYTES)) + { + ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; + return MATRIXSSL_ERROR; + } + if (ssl->sec.x25519KeyPub != NULL) + { + psFree(ssl->sec.x25519KeyPub, ssl->sec.eccDhKeyPool); + } + ssl->sec.x25519KeyPub = psMalloc(ssl->sec.eccDhKeyPool, + PS_DH_X25519_PUBLIC_KEY_BYTES); + Memcpy(ssl->sec.x25519KeyPub, + c, + PS_DH_X25519_PUBLIC_KEY_BYTES); + c += PS_DH_X25519_PUBLIC_KEY_BYTES; + sigStop = c; +# ifdef USE_SSL_INFORMATIONAL_TRACE + ssl->peerKeyExKeyType = PS_X25519; + ssl->peerKeyExKeyNBits = 256; +# endif + goto verify_sig; + } +# endif /* USE_X25519 */ /* Return -1 if this isn't a curve we specified in client hello */ if (getEccParamById(i, &curve) < 0) @@ -2105,6 +2092,9 @@ int32 parseServerKeyExchange(ssl_t *ssl, { return SSL_MEM_ERROR; } +# ifdef USE_ROT_ECC + ssl->sec.eccKeyPub->rotKeyType = ps_ecc_key_type_ecdhe; +# endif if (psEccX963ImportKey(ssl->hsPool, c, i, ssl->sec.eccKeyPub, curve) < 0) { @@ -2259,26 +2249,38 @@ int32 parseServerKeyExchange(ssl_t *ssl, # endif /* USE_ECC_CIPHER_SUITE */ /* We are still within if (ssl->flags & SSL_FLAGS_DHE_KEY_EX). */ - +# ifdef USE_X25519 + verify_sig: +# endif +# ifndef USE_ONLY_PSK_CIPHER_SUITE /* This layer of authentation is at the key exchange level. The server has sent a signature of the key material that the client can validate here. */ - rc = tlsVerify(ssl, - sigStart, - sigStop - sigStart, - c, - end, - &ssl->sec.cert->publicKey, - NULL); - if (rc < 0) { - return rc; + psVerifyOptions_t opts = {0}; + +# ifdef USE_ROT_ECC + opts.noPreHash = PS_TRUE; +# endif + rc = tlsVerify(ssl, + sigStart, + sigStop - sigStart, + c, + end, + &ssl->sec.cert->publicKey, + &opts); + if (rc < 0) + { + psTraceErrr("ServerKeyExchange sig verification failed\n"); + return rc; + } } /* Signature OK. */ c += rc; /* tlsVerify returns number of consumed octets. */ ssl->hsState = SSL_HS_SERVER_HELLO_DONE; +# endif /* USE_ONLY_PSK_CIPHER_SUITE */ } /* endif (ssl->flags & SSL_FLAGS_DHE_KEY_EX) */ # endif /* USE_DHE_CIPHER_SUITE */ @@ -2446,6 +2448,20 @@ int32 parseServerHelloDone(ssl_t *ssl, int32 hsLen, unsigned char **cp, { /* Set up our private side of the ECC key based on the agreed upon curve */ +# ifdef USE_X25519 + if (ssl->sec.peerCurveId == namedgroup_x25519) + { + psRes_t res; + + res = psDhX25519GenKey(ssl->sec.x25519KeyPriv.priv, + ssl->sec.x25519KeyPriv.pub); + if (res < 0) + { + return PS_FAILURE; + } + goto keygen_done; + } +# endif if (psEccNewKey(ssl->sec.eccDhKeyPool, &ssl->sec.eccKeyPriv, ssl->sec.eccKeyPub->curve) < 0) { @@ -2494,6 +2510,10 @@ int32 parseServerHelloDone(ssl_t *ssl, int32 hsLen, unsigned char **cp, } # endif /* USE_DHE_CIPHER_SUITE */ +# ifdef USE_X25519 +keygen_done: +# endif + ssl->hsState = SSL_HS_FINISHED; *cp = c; @@ -2561,14 +2581,16 @@ int32 parseCertificateRequest(ssl_t *ssl, if (end - c < 2) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid SigHash in Certificate Request message (short header)\n"); + psTraceErrr("Invalid SigHash in Certificate Request message "\ + "(short header)\n"); return MATRIXSSL_ERROR; } len = GETSHORT(c); c += 2; if (end - c < len) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid SigHash in Certificate Request message (short message)\n"); + psTraceErrr("Invalid SigHash in Certificate Request message " \ + "(short message)\n"); return MATRIXSSL_ERROR; } /* Parse supported_signature_algorithms list. */ @@ -2584,9 +2606,10 @@ int32 parseCertificateRequest(ssl_t *ssl, keySelect->peerSigAlgsLen = nSigAlg; keySelect->peerSigAlgMask = ssl->serverSigAlgs; c += len; -# ifdef USE_SSL_INFORMATIONAL_TRACE_VERBOSE - psTracePrintSigAlgs(ssl->serverSigAlgs, "Peer CertificateRequest"); -# endif + psTracePrintSigAlgs(INDENT_HS_MSG, + "supported_signature_algorithms", + ssl->serverSigAlgs, + PS_TRUE); } else { @@ -2604,7 +2627,8 @@ int32 parseCertificateRequest(ssl_t *ssl, if (end - c < len) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid Certificate Request message (short CA's header)\n"); + psTraceErrr("Invalid Certificate Request message " \ + "(short CA's header)\n"); return MATRIXSSL_ERROR; } /* Count the number of CA's */ @@ -2615,7 +2639,8 @@ int32 parseCertificateRequest(ssl_t *ssl, if (certLen == 0 || (end - c) < certLen || certLen > len) { ssl->err = SSL_ALERT_DECODE_ERROR; - psTraceErrr("Invalid CertificateRequest message (short CA data)\n"); + psTraceErrr("Invalid CertificateRequest message " \ + "(short CA data)\n"); return MATRIXSSL_ERROR; } c += certLen; @@ -2623,24 +2648,36 @@ int32 parseCertificateRequest(ssl_t *ssl, nCas++; } - /* Fill in keySelect - we have now checked the data, so taking the easy path. */ + /* Fill in keySelect - we have now checked the data, + so taking the easy path. */ keySelect->nCas = nCas; - keySelect->caNames = psCalloc(ssl->hsPool, nCas, sizeof(keySelect->caNames[0])); - keySelect->caNameLens = psCalloc(ssl->hsPool, nCas, sizeof(keySelect->caNameLens[0])); - if (keySelect->caNames == NULL || keySelect->caNameLens == NULL) + keySelect->caNames = psCalloc( + ssl->hsPool, + nCas, + sizeof(keySelect->caNames[0])); + keySelect->caNameLens = psCalloc( + ssl->hsPool, + nCas, + sizeof(keySelect->caNameLens[0])); + if (nCas > 0) { - psFree(keySelect->caNames, ssl->hsPool); - psFree(keySelect->caNameLens, ssl->hsPool); - ssl->err = SSL_ALERT_INTERNAL_ERROR; - return MATRIXSSL_ERROR; + if (keySelect->caNames == NULL || keySelect->caNameLens == NULL) + { + psFree(keySelect->caNames, ssl->hsPool); + psFree(keySelect->caNameLens, ssl->hsPool); + ssl->err = SSL_ALERT_INTERNAL_ERROR; + return MATRIXSSL_ERROR; + } } for (nCas = 0; nCas < keySelect->nCas; nCas++) { /* NOTE: caNames points to the original TLS record data, and pointers are valid only as long as the packet is valid. */ - keySelect->caNameLens[nCas] = GETSHORT(c0); c0 += 2; - keySelect->caNames[nCas] = c0; c0 += keySelect->caNameLens[nCas]; + keySelect->caNameLens[nCas] = GETSHORT(c0); + c0 += 2; + keySelect->caNames[nCas] = c0; + c0 += keySelect->caNameLens[nCas]; } } @@ -2730,6 +2767,8 @@ int32 parseFinished(ssl_t *ssl, int32 hsLen, { ssl->err = SSL_ALERT_DECRYPT_ERROR; psTraceErrr("Invalid handshake msg hash\n"); + psTraceBytes("recv", c, hsLen); + psTraceBytes("have", hsMsgHash, hsLen); return MATRIXSSL_ERROR; } #ifdef ENABLE_SECURE_REHANDSHAKES @@ -2761,6 +2800,7 @@ int32 parseFinished(ssl_t *ssl, int32 hsLen, /* Server side resumed completion */ matrixSslPrintHSDetails(ssl); #endif + sslFreeHSHash(ssl); } } else /* We are the client. */ @@ -2789,6 +2829,7 @@ int32 parseFinished(ssl_t *ssl, int32 hsLen, /* Client side standard completion */ matrixSslPrintHSDetails(ssl); #endif + sslFreeHSHash(ssl); } } #ifndef USE_ONLY_PSK_CIPHER_SUITE @@ -3192,14 +3233,18 @@ RESUME_VALIDATE_CERTS: so store information about the public key, to be logged later in matrixSslPrintHSDetails. */ ssl->peerAuthKeyType = ssl->sec.cert->publicKey.type; +#ifdef USE_RSA if (ssl->peerAuthKeyType == PS_RSA) { ssl->peerAuthKeyNBits = ssl->sec.cert->publicKey.keysize * 8; } - else +#endif +#ifdef USE_ECC + if (ssl->peerAuthKeyType == PS_ECC || ssl->peerAuthKeyType == PS_ED25519) { ssl->peerAuthKeyNBits = ssl->sec.cert->publicKey.key.ecc.curve->size * 8; } +#endif # endif /* USE_SSL_INFORMATIONAL_TRACE */ /* The last thing we want to check before passing the certificates to diff --git a/matrixssl/hsHash.c b/matrixssl/hsHash.c index 73ed3c2..ab2fed9 100644 --- a/matrixssl/hsHash.c +++ b/matrixssl/hsHash.c @@ -2,7 +2,8 @@ * @file hsHash.c * @version $Format:%h%d$ * - * "Native" handshake hash for SSL 3.0 and TLS 1.0/1.1/1.2. + * Standard handshake hash for implementation for SSL 3.0 and + * TLS 1.0/1.1/1.2. */ /* * Copyright (c) 2013-2018 INSIDE Secure Corporation @@ -33,6 +34,8 @@ #include "matrixsslImpl.h" +#ifndef USE_BUFFERED_HS_HASH + #ifdef USE_NATIVE_TLS_HS_HASH # define FINISHED_LABEL_SIZE 15 @@ -330,7 +333,7 @@ static int32_t tlsGenerateFinishedHash(ssl_t *ssl, else { /* Overloading this function to handle the client auth needs of - handshake hashing. */ + handshake hashing. TODO: use a separate function! */ # ifdef USE_TLS_1_2 if (ACTV_VER(ssl, v_tls_sha2)) { @@ -465,9 +468,29 @@ int32_t extMasterSecretSnapshotHSHash(ssl_t *ssl, unsigned char *out, a hash of the preceeding handshake messages for comparison to incoming message. */ -int32_t sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, int32 senderFlag) +int32_t sslSnapshotHSHash(ssl_t *ssl, + unsigned char *out, + psBool_t sender, + psBool_t isFinishedHash) { int32 len = PS_FAILURE; + int32_t senderFlag; + + /* Fill senderFlag for compability. The old tlsGenerateFinishedHash + and sslGenerateFinishedHash APIs still use the senderFlag param + with confusing semantics. */ + if (sender) + { + senderFlag = (ssl->flags & SSL_FLAGS_SERVER); + } + else + { + senderFlag = (ssl->flags & SSL_FLAGS_SERVER) ? 0 : SSL_FLAGS_SERVER; + } + if (!isFinishedHash) + { + senderFlag = -1; + } # ifdef USE_DTLS if (ACTV_VER(ssl, v_dtls_any)) @@ -527,6 +550,14 @@ int32_t sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, int32 senderFlag) return len; } +void sslFreeHSHash(ssl_t *ssl) +{ + /* Standard HS hash implementation does not need to free anything here. */ + (void)ssl; +} + #endif /* USE_NATIVE_TLS_HS_HASH */ +#endif /* USE_BUFFERED_HS_HASH */ + /******************************************************************************/ diff --git a/matrixssl/hsHashBuffered.c b/matrixssl/hsHashBuffered.c new file mode 100644 index 0000000..46ba418 --- /dev/null +++ b/matrixssl/hsHashBuffered.c @@ -0,0 +1,262 @@ +/** + * @file hsHashBuffered.c + * @version $Format:%h%d$ + * + * Buffered handshake hash implementation for TLS. + */ +/* + * Copyright (c) 2013-2019 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "matrixsslImpl.h" + +#ifdef USE_BUFFERED_HS_HASH + +# define FINISHED_LABEL_SIZE 15 +# define LABEL_CLIENT "client finished" +# define LABEL_SERVER "server finished" + +# ifndef HS_MSG_BUF_INITIAL_SIZE +# define HS_MSG_BUF_INITIAL_SIZE 2048 +# endif +# ifndef HS_MSG_BUF_SIZE_INCREMENT +# define HS_MSG_BUF_SIZE_INCREMENT 1024 +# endif + +# ifndef DEBUG_HS_HASH_ROT +/* # define DEBUG_HS_HASH_ROT */ /* Enable hex dump of hashed data. */ +# endif + +int32_t sslInitHSHash(ssl_t *ssl) +{ + ssl->hsMsgBuf.start = psMalloc(ssl->hsPool, HS_MSG_BUF_INITIAL_SIZE); + if (ssl->hsMsgBuf.start == NULL) + { + psTraceErrr("Out of mem in sslInitHSHash\n"); + return PS_MEM_FAIL; + } + ssl->hsMsgBuf.size = HS_MSG_BUF_INITIAL_SIZE; + ssl->hsMsgBuf.buf = ssl->hsMsgBuf.start; + ssl->hsMsgBuf.end = ssl->hsMsgBuf.start + ssl->hsMsgBuf.size; + + return PS_SUCCESS; +} + +void sslFreeHSHash(ssl_t *ssl) +{ + if (ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start > 0) + { + psTraceIntInfo("Total handshake message size: %tu bytes\n", + ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start); + } + psFree(ssl->hsMsgBuf.start, ssl->hsPool); + ssl->hsMsgBuf.start = NULL; + ssl->hsMsgBuf.end = NULL; + ssl->hsMsgBuf.buf = NULL; + ssl->hsMsgBuf.size = 0; + ssl->hsMsgCHtoCKELen = 0; +} + +/******************************************************************************/ +/** + Add the given data to the running hash of the handshake messages. + @param[in,out] ssl TLS context + @param[in] in Pointer to handshake data to hash. + @param[in] len Number of bytes of handshake data to hash. + @return < 0 on failure. + */ +int32_t sslUpdateHSHash(ssl_t *ssl, const unsigned char *in, psSize_t len) +{ + psSizeL_t bufferedLen, remainingLen; + unsigned char *tmp; + psSizeL_t newLen; + + if (ssl->hsMsgBuf.buf == NULL || ssl->hsMsgBuf.size <= 0) + { + return PS_ARG_FAIL; + } + +#ifdef USE_TLS_1_3 + /* If we just received ClientHello, so no version has been negoatiated + yet. Instead, check for TLS 1.3 support. */ + if (anyTls13VersionSupported(ssl) && + (ssl->hsState == SSL_HS_CLIENT_HELLO)) + { + /* Postpone updating the hash. This is because if the CH contains + any PSK binders, we need to hash it in two parts in order to + generate the binder key. We shall update the hash either in + tls13VerifyBinder, if binders are present, or in + parseSSLHandshake if not. */ + if (ssl->sec.tls13CHLen == 0) + { + ssl->sec.tls13CHStart = in; + ssl->sec.tls13CHLen = len; + psTraceBytes("Postponing Tr-Hash", in, len); + return PS_SUCCESS; + } + } +#endif + + remainingLen = ssl->hsMsgBuf.end - ssl->hsMsgBuf.buf; + if (len > remainingLen) + { + psTraceInfo("Out of buffer in sslUpdateHSHash\n"); + + bufferedLen = ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start; + newLen = bufferedLen; + while (newLen < bufferedLen + len) + { + newLen += HS_MSG_BUF_SIZE_INCREMENT; + } + tmp = psRealloc(ssl->hsMsgBuf.start, newLen, ssl->hsPool); + if (tmp == NULL) + { + psTraceErrr("Realloc failed in sslUpdateHSHash\n"); + return PS_MEM_FAIL; + } + ssl->hsMsgBuf.start = tmp; + ssl->hsMsgBuf.buf = ssl->hsMsgBuf.start + bufferedLen; + ssl->hsMsgBuf.size = newLen; + ssl->hsMsgBuf.end = ssl->hsMsgBuf.start + ssl->hsMsgBuf.size; + psTraceIntInfo("New HS hash buffer size: %zu\n", newLen); + } + +# ifdef DEBUG_HS_HASH_ROT + psTraceBytes("sslUpdateHSHash", in, len); +# endif + + Memcpy(ssl->hsMsgBuf.buf, in, len); + ssl->hsMsgBuf.buf += len; + + return PS_SUCCESS; +} + +# if defined(USE_SERVER_SIDE_SSL) && defined(USE_CLIENT_AUTH) +int32 sslSha1RetrieveHSHash(ssl_t *ssl, unsigned char *out) +{ + Memcpy(out, ssl->sec.sha1Snapshot, SHA1_HASH_SIZE); + return SHA1_HASH_SIZE; +} + +int32 sslSha384RetrieveHSHash(ssl_t *ssl, unsigned char *out) +{ + Memcpy(out, ssl->sec.sha384Snapshot, SHA384_HASH_SIZE); + return SHA384_HASH_SIZE; +} + +int32 sslSha512RetrieveHSHash(ssl_t *ssl, unsigned char *out) +{ + Memcpy(out, ssl->sec.sha512Snapshot, SHA512_HASH_SIZE); + return SHA512_HASH_SIZE; +} +# endif /* USE_SERVER_SIDE_SSL && USE_CLIENT_AUTH */ + +int32_t sslSnapshotHSHash(ssl_t *ssl, + unsigned char *out, + psBool_t sender, + psBool_t isFinishedHash) +{ + unsigned char tmp[FINISHED_LABEL_SIZE + SHA384_HASH_SIZE]; + psSizeL_t hashLen; + int32_t hashAlgId; + psDigestContext_t ctx; + uint32_t flags; + + if (isFinishedHash) + { + /* The server uses the server label when sending, the client uses + the client label when sending. Vice versa when receiving. */ + if (ssl->flags & SSL_FLAGS_SERVER) + { + Memcpy(tmp, + sender ? LABEL_SERVER : LABEL_CLIENT, + FINISHED_LABEL_SIZE); + } + else + { + Memcpy(tmp, + sender ? LABEL_CLIENT : LABEL_SERVER, + FINISHED_LABEL_SIZE); + } + } + + if (ssl->cipher->flags & CRYPTO_FLAGS_SHA3) + { + hashLen = SHA384_HASH_SIZE; + hashAlgId = OID_SHA384_ALG; + flags = CRYPTO_FLAGS_SHA3; + } + else + { + hashLen = SHA256_HASH_SIZE; + hashAlgId = OID_SHA256_ALG; + flags = CRYPTO_FLAGS_SHA2; + } + + psHashInit(&ctx, hashAlgId, NULL); + psHashUpdate( + &ctx, + ssl->hsMsgBuf.start, + ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start); + + if (isFinishedHash) + { + /* Produce verify_data for the Finished message. */ + psHashFinal(&ctx, tmp + FINISHED_LABEL_SIZE); + return prf2( + ssl->sec.masterSecret, + SSL_HS_MASTER_SIZE, + tmp, + FINISHED_LABEL_SIZE + hashLen, + out, + TLS_HS_FINISHED_SIZE, + flags); + } + else + { + /* Produce a raw handshake hash. */ + psHashFinal(&ctx, tmp); + Memcpy(out, tmp, hashLen); + } + + return hashLen; +} + +int32_t extMasterSecretSnapshotHSHash(ssl_t *ssl, unsigned char *out, + uint32 *outLen) +{ + uint32_t len; + + len = sslSnapshotHSHash(ssl, out, PS_TRUE, PS_FALSE); + *outLen = len; + + ssl->hsMsgCHtoCKELen = ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start; + + return *outLen; +} +#endif /* USE_BUFFERED_HS_HASH */ + +/******************************************************************************/ diff --git a/matrixssl/matrixssl.c b/matrixssl/matrixssl.c index d367f91..4446c74 100644 --- a/matrixssl/matrixssl.c +++ b/matrixssl/matrixssl.c @@ -323,7 +323,7 @@ int32_t matrixSslGetMaxEarlyData(ssl_t *ssl) return PS_ARG_FAIL; } - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { /* For server this is not really relevant but return the global maximum */ @@ -541,7 +541,7 @@ int32 matrixSslNewSession(ssl_t **ssl, const sslKeys_t *keys, lssl->userDataPtr = options->userDataPtr; } -#ifdef USE_ECC +#if defined(USE_ECC) /* If user specified EC curves they support, let's check that against the key material they provided so there are no conflicts. Don't need to test against default compiled-in curves because the keys @@ -843,6 +843,8 @@ void matrixSslDeleteSession(ssl_t *ssl) psSha1Sync(NULL, 1); #endif /* USE_TLS_1_2 */ + sslFreeHSHash(ssl); + /* If we have a sessionId, for servers we need to clear the inUse flag in the session cache so the ID can be replaced if needed. In the client case @@ -877,6 +879,17 @@ void matrixSslDeleteSession(ssl_t *ssl) { matrixSslDeleteHelloExtension(ssl->userExt); } +# ifdef ENABLE_SECURE_REHANDSHAKES + if (!(ssl->flags & SSL_FLAGS_SERVER)) + { + if (ssl->tlsClientCipherSuites != NULL) + { + psFree(ssl->tlsClientCipherSuites, ssl->hsPool); + ssl->tlsClientCipherSuites = NULL; + ssl->tlsClientCipherSuitesLen = 0; + } + } +# endif #endif #if defined(USE_IDENTITY_CERTIFICATES) @@ -1083,14 +1096,6 @@ void matrixSslGetAnonStatus(ssl_t *ssl, int32 *certArg) *certArg = ssl->sec.anon; } -/******************************************************************************/ -/** - @return PS_TRUE if we've completed the SSL handshake. PS_FALSE otherwise. - */ -int32_t matrixSslHandshakeIsComplete(const ssl_t *ssl) -{ - return (ssl->hsState == SSL_HS_DONE) ? PS_TRUE : PS_FALSE; -} # ifdef ENABLE_SECURE_REHANDSHAKES /** diff --git a/matrixssl/matrixsslApi.c b/matrixssl/matrixsslApi.c index 25acf28..e73af4c 100644 --- a/matrixssl/matrixsslApi.c +++ b/matrixssl/matrixsslApi.c @@ -475,7 +475,7 @@ psBool_t matrixSslClientCertUpdated(ssl_t *ssl) if (ssl->extClientCertKeyStateFlags != EXT_CLIENT_CERT_KEY_STATE_WAIT_FOR_CERT_KEY_UPDATE) { - psTraceInfo("Error: wrong state for client cert update\n"); + psTraceErrr("Error: wrong state for client cert update\n"); return PS_FALSE; } else @@ -502,7 +502,7 @@ psBool_t matrixSslClientPrivKeyUpdated(ssl_t *ssl) if (ssl->extClientCertKeyStateFlags != EXT_CLIENT_CERT_KEY_STATE_WAIT_FOR_CERT_KEY_UPDATE) { - psTraceInfo("Error: wrong state for client key update\n"); + psTraceErrr("Error: wrong state for client key update\n"); return PS_FALSE; } else @@ -697,28 +697,6 @@ int32_t matrixSslSetCvSignature(ssl_t *ssl, const unsigned char *sig, const size < 0 on error */ -int32 matrixSslNewServer(ssl_t **ssl, - pubkeyCb_t pubkeyCb, - pskCb_t pskCb, - sslCertCb_t certCb, - sslSessOpts_t *options) -{ - int32 rc; - - if ((rc = matrixSslNewServerSession(ssl, NULL, - certCb, - options)) < 0) - { - return rc; - } - - (*ssl)->sec.pskCb = (pskCb_t) pskCb; -# ifndef USE_ONLY_PSK_CIPHER_SUITE - (*ssl)->sec.pubkeyCb = (pubkeyCb_t) pubkeyCb; -# endif - return MATRIXSSL_SUCCESS; -} - int32 matrixSslNewServerSession(ssl_t **ssl, const sslKeys_t *keys, sslCertCb_t certCb, sslSessOpts_t *options) @@ -1991,7 +1969,7 @@ int32_t matrixSslEncodeRehandshake(ssl_t *ssl, sslKeys_t *keys, /* Resend epoch should be brought up-to-date with new epoch */ ssl->resendEpoch[0] = ssl->epoch[0]; ssl->resendEpoch[1] = ssl->epoch[1]; - + ssl->appDataExch = 0; ssl->msn = ssl->resendMsn = 0; } # endif /* USE_DTLS */ @@ -2044,7 +2022,7 @@ L_REHANDSHAKE: } if ((rc = matrixSslEncodeClientHello(ssl, &sbuf, cipherSpec, - cipherSpecLen, &reqLen, NULL, &options)) < 0) + cipherSpecLen, &reqLen, ssl->userExt, &options)) < 0) { if (rc == SSL_FULL && newLen == 0) { @@ -2217,6 +2195,7 @@ int32 matrixSslSentData(ssl_t *ssl, uint32 bytes) /* Client side resumed completion or server standard completion */ matrixSslPrintHSDetails(ssl); # endif + sslFreeHSHash(ssl); } return rc; } @@ -2241,7 +2220,7 @@ int32_t matrixSslSetTls13BlockPadding(ssl_t *ssl, psSizeL_t blockSize) } if (blockSize > TLS_1_3_MAX_PLAINTEXT_FRAGMENT_LEN) { - psTraceInfo("Error: cannot pad to larger than max plaintext size\n"); + psTraceErrr("Error: cannot pad to larger than max plaintext size\n"); return PS_ARG_FAIL; } ssl->tls13BlockSize = blockSize; @@ -2253,4 +2232,37 @@ int32_t matrixSslSetTls13BlockPadding(ssl_t *ssl, psSizeL_t blockSize) } # endif /* USE_TLS_1_3 */ +sslKeys_t *matrixSslGetKeys(ssl_t *ssl) +{ + return ssl->keys; +} + +psProtocolVersion_t matrixSslGetNegotiatedVersion(ssl_t *ssl) +{ + return GET_NGTD_VER(ssl); +} + +psProtocolVersion_t matrixSslVersionFromMinorDigit(uint16_t digit) +{ + return DIGIT_TO_VER(digit); +} + +psBool_t matrixSslHandshakeIsComplete(const ssl_t *ssl) +{ + return (ssl->hsState == SSL_HS_DONE) ? PS_TRUE : PS_FALSE; +} + +psX509Cert_t* sslKeysGetCACerts(const sslKeys_t *keys) +{ +# ifdef USE_ONLY_PSK_CIPHER_SUITE + return NULL; +# else + return keys->CAcerts; +# endif +} + +char *matrixSslGetExpectedName(const ssl_t *ssl) +{ + return ssl->expectedName; +} /******************************************************************************/ diff --git a/matrixssl/matrixsslApi.h b/matrixssl/matrixsslApi.h index d573b3a..9948489 100644 --- a/matrixssl/matrixsslApi.h +++ b/matrixssl/matrixsslApi.h @@ -41,282 +41,41 @@ extern "C" { # endif -# include "coreApi.h" /* cryptoApi.h and matrixsslApi.h depend on this */ -# include "../crypto/cryptoApi.h" /* matrixsslApi.h depend on cryptoApi.h. */ +# include "matrixsslApiPre.h" /* Preamble. */ +# include "matrixsslApiVer.h" /* Protocol version constants and macros. */ +# include "matrixsslCheck.h" /* Do sanity checks on configuration. */ +# include "matrixsslApiRet.h" /* Return codes. */ +# include "matrixsslApiAlert.h" /* Constants for TLS protocol alerts. */ +# include "matrixsslApiCipher.h" /* Ciphersuite ID constants. */ +# include "matrixsslApiLimits.h" /* Global minima and maxima. */ +# include "matrixsslApiExt.h" /* TLS extension IDs. */ +# include "matrixsslApiCipher.h" /* Ciphersuite IDs. */ +# include "matrixsslApiTypes.h" /* TLS and configuration data types. */ -# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST -# include /* Get matrixssl configuration from -I dir. */ -# else -# include "matrixsslConfig.h" /* Get local matrixssl configuration file. */ -# endif +/* For API documentation, see the separate MatrixSSL APIs manual. */ +/* Library initialization. */ +# define matrixSslOpen() \ + matrixSslOpenWithConfig(MATRIXSSL_CONFIG) +PSPUBLIC int32 matrixSslOpenWithConfig( + const char *config); +PSPUBLIC void matrixSslClose(void); -/** - - USE_TLS versions must 'stack' for compiling purposes - - must enable TLS if enabling TLS 1.1 - - must enable TLS 1.1 if enabling TLS 1.2 - - Use the DISABLE_TLS_ defines to disallow specific protocols at runtime - that have been enabled via USE_TLS_. - - There is no DISABLE_TLS_ for the latest version of the protocol. If - you don't want to use that version disable the USE_TLS_ define instead - The USE_TLS_1_x_AND_ABOVE simplifies this configuration. - @security To enable SSL3.0, see below. - */ -# define USE_TLS /**< DO NOT DISABLE @security NIST_MAY */ -# define USE_TLS_1_1 /**< DO NOT DISABLE @security NIST_SHALL */ -# define USE_TLS_1_2 /**< DO NOT DISABLE @security NIST_SHOULD */ -# define DISABLE_SSLV3 /**< DO NOT DISABLE, undef below if required - @security NIST_SHALL_NOT */ - -# ifndef NO_TLS_1_2_TOGGLE -# define USE_TLS_1_2_TOGGLE /**< Allow disabling TLS 1.2 dynamically. */ -# endif -# ifndef NO_TLS_1_1_TOGGLE -# define USE_TLS_1_1_TOGGLE /**< Allow disabling TLS 1.1 dynamically. */ -# endif - # ifndef NO_TLS_1_0_TOGGLE -# define USE_TLS_1_0_TOGGLE /**< Allow disabling TLS 1.0 dynamically. */ -# endif - -/* This looks a bit clumsy, because TLS 1.3 code still requires a separate - define (USE_TLS_1_3) to enable. */ -# if defined USE_TLS_1_2_AND_ABOVE -# define USE_TLS_1_3 -# define USE_TLS_1_2 -# define DISABLE_TLS_1_1 -# define DISABLE_TLS_1_0 -# elif defined USE_TLS_1_1_AND_ABOVE -# define USE_TLS_1_3 -# define USE_TLS_1_2 -# define DISABLE_TLS_1_0 -# elif defined USE_TLS_1_0_AND_ABOVE -# define USE_TLS_1_3 -# define USE_TLS_1_2 -# define USE_TLS_1_1 -/** @security undef DISABLE_SSLV3 here if required */ -# else -# error Must define USE_TLS_1_x_AND_ABOVE -# endif - -/* Type used for storing protocol versions. */ -typedef uint32_t psProtocolVersion_t; - -# if defined(USE_TLS_1_3) && defined(DISABLE_TLS_1_3) -# undef USE_TLS_1_3 -# undef USE_TLS_AES_128_GCM_SHA256 -# undef USE_TLS_AES_256_GCM_SHA384 -# undef USE_TLS_CHACHA20_POLY1305_SHA256 -# endif - -/** - Do sanity checks on configuration. - */ -# include "matrixsslCheck.h" - - - - -# include "version.h" - -# ifdef USE_MATRIX_OPENSSL_LAYER -# include "opensslApi.h" -# endif -# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING -# include "psExt.h" -# endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ - -/******************************************************************************/ -/* - Public return codes - */ -# define MATRIXSSL_SUCCESS PS_SUCCESS /* Generic success */ -# define MATRIXSSL_ERROR PS_PROTOCOL_FAIL /* Generic SSL error */ -# define MATRIXSSL_REQUEST_SEND 1 /* API produced data to be sent */ -# define MATRIXSSL_REQUEST_RECV 2 /* API requres more data to continue */ -# define MATRIXSSL_REQUEST_CLOSE 3 /* API indicates clean close is req'd */ -# define MATRIXSSL_APP_DATA 4 /* App data is avail. to caller */ -# define MATRIXSSL_HANDSHAKE_COMPLETE 5 /* Handshake completed */ -# define MATRIXSSL_RECEIVED_ALERT 6 /* An alert was received */ -# define MATRIXSSL_APP_DATA_COMPRESSED 7 /* App data must be inflated */ - -/* Early_data return codes */ -# ifdef USE_TLS_1_3 -# define MATRIXSSL_EARLY_DATA_ACCEPTED 8 -# define MATRIXSSL_EARLY_DATA_REJECTED 9 -# define MATRIXSSL_EARLY_DATA_SENT 10 -# define MATRIXSSL_EARLY_DATA_NOT_SENT 11 - -# endif -/******************************************************************************/ -/* - Build the configuration string with the relevant build options for - runtime validation of compile-time configuration. - */ -# define HW_CONFIG_STR "N" - -# define MATRIXSSL_CONFIG \ - "Y" \ - HW_CONFIG_STR \ - PSCRYPTO_CONFIG - - -/* Maximum number of simultaneous TLS versions supported */ -# define TLS_MAX_SUPPORTED_VERSIONS 16 -/* TLS 1.3: maximum number of algorithms in signature_algorithms extension. */ -# define TLS_MAX_SIGNATURE_ALGORITHMS 32 -/* TLS 1.3: maximum number of cipher suites to support in clientHello */ -# define TLS_1_3_MAX_CIPHER_SUITES 8 -/* TLS 1.3: maximum number of groups. */ -# define TLS_1_3_MAX_GROUPS 32 - -/* - TLS implementations supporting these ciphersuites MUST support - arbitrary PSK identities up to 128 octets in length, and arbitrary - PSKs up to 64 octets in length. Supporting longer identities and - keys is RECOMMENDED. - */ -# define SSL_PSK_MAX_KEY_SIZE 64 /* Must be < 256 due to 'idLen' */ -# define SSL_PSK_MAX_ID_SIZE 128 /* Must be < 256 due to 'idLen' */ -# define SSL_PSK_MAX_HINT_SIZE 32 /* ServerKeyExchange hint is non-standard */ - - - -/* - SSL Alert levels and descriptions - This implementation treats all alerts that are not related to - certificate validation as fatal - */ -# define SSL_ALERT_LEVEL_WARNING 1 -# define SSL_ALERT_LEVEL_FATAL 2 - -# define SSL_ALERT_CLOSE_NOTIFY 0 -# define SSL_ALERT_UNEXPECTED_MESSAGE 10 -# define SSL_ALERT_BAD_RECORD_MAC 20 -# define SSL_ALERT_DECRYPTION_FAILED 21/* Do not use, per RFC 5246 */ -# define SSL_ALERT_RECORD_OVERFLOW 22 -# define SSL_ALERT_DECOMPRESSION_FAILURE 30 -# define SSL_ALERT_HANDSHAKE_FAILURE 40 -# define SSL_ALERT_NO_CERTIFICATE 41 -# define SSL_ALERT_BAD_CERTIFICATE 42 -# define SSL_ALERT_UNSUPPORTED_CERTIFICATE 43 -# define SSL_ALERT_CERTIFICATE_REVOKED 44 -# define SSL_ALERT_CERTIFICATE_EXPIRED 45 -# define SSL_ALERT_CERTIFICATE_UNKNOWN 46 -# define SSL_ALERT_ILLEGAL_PARAMETER 47 -# define SSL_ALERT_UNKNOWN_CA 48 -# define SSL_ALERT_ACCESS_DENIED 49 -# define SSL_ALERT_DECODE_ERROR 50 -# define SSL_ALERT_DECRYPT_ERROR 51 -# define SSL_ALERT_PROTOCOL_VERSION 70 -# define SSL_ALERT_INSUFFICIENT_SECURITY 71 -# define SSL_ALERT_INTERNAL_ERROR 80 -# define SSL_ALERT_INAPPROPRIATE_FALLBACK 86 -# define SSL_ALERT_NO_RENEGOTIATION 100 -# define SSL_ALERT_UNSUPPORTED_EXTENSION 110 -# define SSL_ALERT_UNRECOGNIZED_NAME 112 -# define SSL_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 113 -# define SSL_ALERT_UNKNOWN_PSK_IDENTITY 115 -# define SSL_ALERT_NO_APP_PROTOCOL 120 - -/** - SSL protocol and MatrixSSL defines. - @see https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml - */ - -/* - Maximum SSL/TLS record size, per specification - */ -# define SSL_MAX_PLAINTEXT_LEN 0x4000 /* 16KB */ -# define SSL_MAX_RECORD_LEN SSL_MAX_PLAINTEXT_LEN + 2048 -# define SSL_MAX_BUF_SIZE 0xffff /* 65536. This must be - enough for entire - outgoing flight */ -# define SSL_MAX_DISABLED_CIPHERS 32 - -/* - From section 5.2. of the TLS 1.3 spec. - Assuming a fullsize TLSPlaintext.fragment, TLSInnerPlaintext adds - 1 type octet and TLSCiphertext adds at most 255 AEAD overhead. -*/ -# define TLS_1_3_MAX_PLAINTEXT_FRAGMENT_LEN 16384 /* 2^14 */ -# define TLS_1_3_MAX_INNER_PLAINTEXT_LEN 16385 /* 2^14 + 1 */ -# define TLS_1_3_MAX_CIPHERTEXT_LEN 16640 /* 2^14 + 1 + 255 */ - -/* - Maximum buffer sizes for static SSL array types - */ -# define SSL_MAX_MAC_SIZE 48/* SHA384 */ -# define SSL_MAX_IV_SIZE 16 -# define SSL_MAX_BLOCK_SIZE 16 -# define SSL_MAX_SYM_KEY_SIZE 32 -# define MAX_TLS_1_3_HASH_SIZE SHA384_HASHLEN - -/* - Negative return codes must be between -50 and -69 in the MatrixSSL module - */ -# define SSL_FULL -50 /* must call sslRead before decoding */ -# define SSL_PARTIAL -51 /* more data reqired to parse full msg */ -# define SSL_SEND_RESPONSE -52 /* decode produced output data */ -# define SSL_PROCESS_DATA -53 /* succesfully decoded application data */ -# define SSL_ALERT -54 /* we've decoded an alert */ -# define SSL_FILE_NOT_FOUND -55 /* File not found */ -# define SSL_MEM_ERROR PS_MEM_FAIL /* Memory allocation failure */ -# ifdef USE_DTLS -# define DTLS_MUST_FRAG -60 /* Message must be fragmented */ -# define DTLS_RETRANSMIT -61 /* Received a duplicate hs msg from peer */ -# endif /* USE_DTLS */ -# define SSL_ENCODE_RESPONSE -62 /* Need to encode a response. */ -# define SSL_NO_TLS_1_3 -63 /* We advertised TLS 1.3, but server - chose TLS <1.3. */ - -/* Forward declarations for certain public API opaque data types. */ -typedef struct ssl ssl_t; -typedef struct sslKeys sslKeys_t; -typedef struct sslKeySelectInfo sslKeySelectInfo_t; -typedef struct sslSessOpts sslSessOpts_t; -typedef struct sslSessionId sslSessionId_t; -typedef struct tlsHelloExt tlsExtension_t; - -# ifdef USE_TLS_1_3 -typedef struct psTls13SessionParams psTls13SessionParams_t; -typedef struct psTls13Psk psTls13Psk_t; -# endif /* USE_TLS_1_3 */ - -/******************************************************************************/ -/* - * Library init and close - */ -# define matrixSslOpen() matrixSslOpenWithConfig(MATRIXSSL_CONFIG) -PSPUBLIC int32 matrixSslOpenWithConfig(const char *config); -PSPUBLIC void matrixSslClose(void); - -/******************************************************************************/ -/* - * Certificate and key material loading - */ -PSPUBLIC int32 matrixSslNewKeys(sslKeys_t **keys, void *poolUserPtr); -PSPUBLIC void matrixSslDeleteKeys(sslKeys_t *keys); - -#define LOAD_KEYS_OPT_ALLOW_OUT_OF_DATE_CERT_PARSE (1 << 0) -typedef struct { - uint32_t flags; /* LOAD_KEYS_OPT_* */ - int32_t key_type; -} matrixSslLoadKeysOpts_t; - -# if defined(USE_RSA) || defined(USE_ECC) - -/* These functions load key and certificate data into a keychain 'keys'. - Calls to function must specify a key/cert pair, and/or a CA certificate. - These functions can be called more than once to input multiple identity - keys to be used for TLS client authentication (in case of a client with - more than one identity known at the time a connection is established. */ -int32_t matrixSslLoadKeys(sslKeys_t *keys, +/* Key and certificate loading. */ +PSPUBLIC int32 matrixSslNewKeys( + sslKeys_t **keys, + void *poolUserPtr); +PSPUBLIC void matrixSslDeleteKeys( + sslKeys_t *keys); +PSPUBLIC int32_t matrixSslLoadKeys( + sslKeys_t *keys, const char *certFile, const char *privFile, const char *privPass, const char *CAfile, matrixSslLoadKeysOpts_t *opts); -int32_t matrixSslLoadKeysMem(sslKeys_t *keys, +PSPUBLIC int32_t matrixSslLoadKeysMem( + sslKeys_t *keys, const unsigned char *certBuf, int32 certLen, const unsigned char *privBuf, @@ -324,44 +83,29 @@ int32_t matrixSslLoadKeysMem(sslKeys_t *keys, const unsigned char *CAbuf, int32 CAlen, matrixSslLoadKeysOpts_t *opts); -# endif /* USE_RSA || USE_ECC */ -# ifdef USE_RSA -PSPUBLIC int32 matrixSslLoadRsaKeysExt(sslKeys_t *keys, - const char *certFile, - const char *privFile, - const char *privPass, - const char *trustedCAFile, - matrixSslLoadKeysOpts_t *opts); -PSPUBLIC int32 matrixSslLoadRsaKeys(sslKeys_t *keys, - const char *certFile, - const char *privFile, - const char *privPass, - const char *trustedCAFile); -PSPUBLIC int32 matrixSslLoadRsaKeysMemExt(sslKeys_t *keys, - const unsigned char *certBuf, - int32 certLen, - const unsigned char *privBuf, - int32 privLen, - const unsigned char *trustedCABuf, - int32 trustedCALen, - matrixSslLoadKeysOpts_t *opts); -PSPUBLIC int32 matrixSslLoadRsaKeysMem(sslKeys_t *keys, - const unsigned char *certBuf, - int32 certLen, - const unsigned char *privBuf, - int32 privLen, - const unsigned char *trustedCABuf, - int32 trustedCALen); -# endif /* USE_RSA */ - -PSPUBLIC int32 matrixSslLoadPkcs12(sslKeys_t *keys, +PSPUBLIC int32_t matrixSslLoadPsk( + sslKeys_t *keys, + const unsigned char key[SSL_PSK_MAX_KEY_SIZE], + uint8_t keyLen, + const unsigned char id[SSL_PSK_MAX_ID_SIZE], + uint8_t idLen); +PSPUBLIC int32_t matrixSslLoadTls13Psk( + sslKeys_t *keys, + const unsigned char *key, + psSize_t keyLen, + const unsigned char *id, + psSize_t idLen, + const psTls13SessionParams_t *params); +PSPUBLIC int32 matrixSslLoadPkcs12( + sslKeys_t *keys, const unsigned char *p12File, const unsigned char *importPass, int32 ipasslen, const unsigned char *macPass, int32 mpasslen, int32 flags); -PSPUBLIC int32 matrixSslLoadPkcs12Mem(sslKeys_t *keys, +PSPUBLIC int32 matrixSslLoadPkcs12Mem( + sslKeys_t *keys, const unsigned char *p12Buf, int32 p12Len, const unsigned char *importPass, @@ -369,170 +113,260 @@ PSPUBLIC int32 matrixSslLoadPkcs12Mem(sslKeys_t *keys, const unsigned char *macPass, int32 mpasslen, int32 flags); - -# ifdef USE_OCSP_RESPONSE -typedef int32_t (*ocspCb_t)(struct ssl *ssl, psOcspResponse_t *response, - psX509Cert_t *cert, int32_t status); -#ifdef USE_SERVER_SIDE_SSL -PSPUBLIC int32_t matrixSslLoadOCSPResponse(sslKeys_t *keys, +PSPUBLIC int32_t matrixSslLoadOCSPResponse( + sslKeys_t *keys, const unsigned char *OCSPResponseBuf, psSize_t OCSPResponseBufLen); -#endif /* USE_SERVER_SIDE_SSL */ -# endif /* USE_OCSP_RESPONSE */ - -/******************************************************************************/ -/* - * Essential public APIs - */ -PSPUBLIC int32 matrixSslGetReadbuf(ssl_t *ssl, unsigned char **buf); -PSPUBLIC int32 matrixSslGetReadbufOfSize(ssl_t *ssl, int32 size, - unsigned char **buf); -PSPUBLIC int32 matrixSslGetOutdata(ssl_t *ssl, unsigned char **buf); -PSPUBLIC int32 matrixSslGetWritebuf(ssl_t *ssl, unsigned char **buf, - uint32 reqLen); -PSPUBLIC int32 matrixSslEncodeWritebuf(ssl_t *ssl, uint32 len); -PSPUBLIC int32 matrixSslEncodeToOutdata(ssl_t *ssl, unsigned char *buf, - uint32 len); -PSPUBLIC int32 matrixSslEncodeToUserBuf(ssl_t *ssl, unsigned char *ptBuf, - uint32 ptLen, unsigned char *ctBuf, uint32 *ctLen); -PSPUBLIC int32 matrixSslSentData(ssl_t *ssl, uint32 bytes); -PSPUBLIC int32 matrixSslReceivedData(ssl_t *ssl, uint32 bytes, - unsigned char **ptbuf, uint32 *ptlen); -PSPUBLIC int32 matrixSslProcessedData(ssl_t *ssl, - unsigned char **ptbuf, uint32 *ptlen); -PSPUBLIC int32 matrixSslEncodeClosureAlert(ssl_t *ssl); -PSPUBLIC void matrixSslDeleteSession(ssl_t *ssl); - -PSPUBLIC psBool_t matrixSslTlsVersionRangeSupported(psProtocolVersion_t low, +/* Session configuration (matrixSslSessOpts* API). */ +PSPUBLIC int32_t matrixSslSessOptsSetServerTlsVersionRange( + sslSessOpts_t *options, + psProtocolVersion_t low, psProtocolVersion_t high); -PSPUBLIC int32_t matrixSslSessOptsSetKeyExGroups(sslSessOpts_t *options, +PSPUBLIC int32_t matrixSslSessOptsSetServerTlsVersions( + sslSessOpts_t *options, + const psProtocolVersion_t versions[], + int32_t versionsLen); +PSPUBLIC int32_t matrixSslSessOptsSetClientTlsVersionRange( + sslSessOpts_t *options, + psProtocolVersion_t low, + psProtocolVersion_t high); +PSPUBLIC int32_t matrixSslSessOptsSetClientTlsVersions( + sslSessOpts_t *options, + const psProtocolVersion_t versions[], + int32_t versionsLen); +PSPUBLIC int32_t matrixSslSessOptsSetKeyExGroups( + sslSessOpts_t *options, uint16_t *namedGroups, psSize_t namedGroupsLen, psSize_t numClientHelloKeyShares); -PSPUBLIC int32_t matrixSslSessOptsSetSigAlgs(sslSessOpts_t *options, +PSPUBLIC int32_t matrixSslSessOptsSetSigAlgs( + sslSessOpts_t *options, uint16_t *sigAlgs, psSize_t sigAlgsLen); -PSPUBLIC int32_t matrixSslSessOptsSetSigAlgsCert(sslSessOpts_t *options, +PSPUBLIC int32_t matrixSslSessOptsSetSigAlgsCert( + sslSessOpts_t *options, uint16_t *sigAlgs, psSize_t sigAlgsLen); -PSPUBLIC int32_t matrixSslSessOptsSetMinDhBits(sslSessOpts_t *options, +PSPUBLIC int32_t matrixSslSessOptsSetMinDhBits( + sslSessOpts_t *options, psSize_t minDhBits); -# ifdef USE_TLS_1_3 -PSPUBLIC int32_t matrixSslGetEarlyDataStatus(ssl_t *ssl); -PSPUBLIC int32_t matrixSslGetMaxEarlyData(ssl_t *ssl); -PSPUBLIC int32_t matrixSslSetTls13BlockPadding(ssl_t *ssl, + +/* Configuring session resumption. */ +PSPUBLIC int32 matrixSslNewSessionId( + sslSessionId_t **sid, + void *poolUserPtr); +PSPUBLIC void matrixSslClearSessionId( + sslSessionId_t *sid); +PSPUBLIC void matrixSslDeleteSessionId( + sslSessionId_t *sid); +PSPUBLIC int32 matrixSslLoadSessionTicketKeys( + sslKeys_t *keys, + const unsigned char name[16], + const unsigned char *symkey, + short symkeyLen, + const unsigned char *hashkey, + short hashkeyLen); +PSPUBLIC int32 matrixSslDeleteSessionTicketKey( + sslKeys_t * keys, + unsigned char name[16]); +PSPUBLIC void matrixSslSetSessionTicketCallback( + sslKeys_t *keys, + int32 (*ticket_cb)(void *, + unsigned char[16], short)); + +/* Configuring extensions. */ +PSPUBLIC void matrixSslRegisterSNICallback( + ssl_t *ssl, + sniCb_t sni_cb); +PSPUBLIC int32 matrixSslCreateSNIext( + psPool_t *pool, + unsigned char *host, + int32 hostLen, + unsigned char **extOut, + int32 *extLen); +PSPUBLIC void matrixSslRegisterALPNCallback( + ssl_t *ssl, + void (*srv_alpn_cb)(void *ssl, + short protoCount, + char *proto[MAX_PROTO_EXT], + int32 protoLen[MAX_PROTO_EXT], + int32 *index)); +PSPUBLIC int32 matrixSslCreateALPNext( + psPool_t *pool, + int32 protoCount, + unsigned char *proto[], + int32 protoLen[], + unsigned char **extOut, + int32 *extLen); + +/* Custom ClientHello extensions. */ +PSPUBLIC int32 matrixSslNewHelloExtension( + tlsExtension_t **extension, + void *poolUserPtr); +PSPUBLIC int32 matrixSslLoadHelloExtension( + tlsExtension_t *extension, + unsigned char *extData, + uint32 length, + uint32 extType); +PSPUBLIC void matrixSslDeleteHelloExtension( + tlsExtension_t *extension); + +/* Creating and deleting sessions. */ +PSPUBLIC int32_t matrixSslNewClientSession( + ssl_t **ssl, + const sslKeys_t *keys, + sslSessionId_t *sid, + const psCipher16_t cipherSpec[], + uint8_t cSpecLen, + sslCertCb_t certCb, + const char *expectedName, + tlsExtension_t *extensions, + sslExtCb_t extCb, + sslSessOpts_t *options); +PSPUBLIC int32_t matrixSslNewServerSession( + ssl_t **ssl, + const sslKeys_t *keys, + sslCertCb_t certCb, + sslSessOpts_t *options); +PSPUBLIC int32_t matrixSslNewServer( + ssl_t **ssl, + pubkeyCb_t pubkeyCb, + pskCb_t pskCb, + sslCertCb_t certCb, + sslSessOpts_t *options); +PSPUBLIC void matrixSslDeleteSession( + ssl_t *ssl); + +/* Handshaking and communicating (the main TLS API). */ +PSPUBLIC int32 matrixSslGetReadbuf( + ssl_t *ssl, + unsigned char **buf); +PSPUBLIC int32 matrixSslGetReadbufOfSize( + ssl_t *ssl, + int32 size, + unsigned char **buf); +PSPUBLIC int32 matrixSslReceivedData( + ssl_t *ssl, + uint32 bytes, + unsigned char **ptbuf, + uint32 *ptlen); +PSPUBLIC int32 matrixSslGetOutdata( + ssl_t *ssl, + unsigned char **buf); +PSPUBLIC int32 matrixSslProcessedData( + ssl_t *ssl, + unsigned char **ptbuf, + uint32 *ptlen); +PSPUBLIC int32 matrixSslSentData( + ssl_t *ssl, + uint32 bytes); +PSPUBLIC int32 matrixSslGetWritebuf( + ssl_t *ssl, + unsigned char **buf, + uint32 reqLen); +PSPUBLIC int32 matrixSslEncodeWritebuf( + ssl_t *ssl, + uint32 len); +PSPUBLIC int32 matrixSslEncodeToOutdata( + ssl_t *ssl, + unsigned char *buf, + uint32 len); +PSPUBLIC int32 matrixSslEncodeToUserBuf( + ssl_t *ssl, + unsigned char *ptBuf, + uint32 ptLen, + unsigned char *ctBuf, + uint32 *ctLen); +PSPUBLIC int32 matrixSslEncodeClosureAlert( + ssl_t *ssl); +PSPUBLIC void matrixSslGetAnonStatus( + ssl_t *ssl, + int32 *anonArg); +# define SSL_OPTION_FULL_HANDSHAKE 1 +PSPUBLIC int32_t matrixSslEncodeRehandshake( + ssl_t *ssl, + sslKeys_t *keys, + sslCertCb_t certCb, + uint32_t sessionOption, + const psCipher16_t cipherSpec[], + uint8_t cSpecLen); +PSPUBLIC int32_t matrixSslGetEarlyDataStatus( + ssl_t *ssl); +PSPUBLIC int32_t matrixSslGetMaxEarlyData( + ssl_t *ssl); +PSPUBLIC psProtocolVersion_t matrixSslGetNegotiatedVersion( + ssl_t *ssl); +PSPUBLIC psBool_t matrixSslHandshakeIsComplete( + const ssl_t *ssl); + +/** Configuration options for a single connection. */ +PSPUBLIC int32 matrixSslDisableRehandshakes( + ssl_t *ssl); +PSPUBLIC int32 matrixSslReEnableRehandshakes( + ssl_t *ssl); +PSPUBLIC int32 matrixSslSetCipherSuiteEnabledStatus( + ssl_t *ssl, + psCipher16_t cipherId, + uint32 status); +PSPUBLIC void matrixSslRegisterSecurityCallback( + ssl_t *ssl, + securityCb_t cb); +PSPUBLIC int32_t matrixSslSetSecurityProfile( + ssl_t *ssl, + psPreDefinedSecProfile_t profile); +PSPUBLIC int32_t matrixSslSetTls13BlockPadding( + ssl_t *ssl, psSizeL_t blockSize); -# endif -/* Callback function of this type is called from the matrix library after it - has performed certificate path construction/validation for the certificate - presented by the peer (either the web server cert, or the client - certificate. This function can accept or reject the tls connection on its - discretion. +/* MatrixDTLS API. */ +PSPUBLIC int32 matrixDtlsSentData( + ssl_t *ssl, + uint32 bytes); +PSPUBLIC int32 matrixDtlsGetOutdata( + ssl_t *ssl, + unsigned char **buf); +PSPUBLIC int32 matrixDtlsSetPmtu( + int32 pmtu); +PSPUBLIC int32 matrixDtlsGetPmtu( + void); - Allowed return values: - * PS_SUCCCESS: - connection is OK - returning this will clear any pending from - potentially failed certificate validation. - * SSL_ALLOW_ANON_CONNECTION: - connection is accepted, but is later considered as anonymous - * >0 TLS alert to send to the peer (one of SSL_ALERT_ codes) - * <0 Internal error; sending SSL_ALERT_INTERNAL_ERROR to peer. */ -typedef int32_t (*sslCertCb_t)(struct ssl *ssl, psX509Cert_t *cert, int32_t alert); +/* Certificate validation APIs. + For documentation, see the MatrixSSL Certificates and CRLs manual. */ +extern int32 matrixValidateCerts( + psPool_t *pool, + psX509Cert_t *subjectCerts, + psX509Cert_t *issuerCerts, + char *expectedName, + psX509Cert_t **foundIssuer, + void *pkiData, + void *userPoolPtr); +extern int32 matrixValidateCertsExt( + psPool_t *pool, + psX509Cert_t *subjectCerts, + psX509Cert_t *issuerCerts, + char *expectedName, + psX509Cert_t **foundIssuer, + void *pkiData, + void *userPoolPtr, + const matrixValidateCertsOptions_t *options); -/** Structure for passing client-side key and cert selection requirements - to the sslIdentityCb_t type callback function. The structure is filled - with information from the server's CertificateRequest message. -*/ -struct sslKeySelectInfo -{ - /* Number of End Entity certificate supplying certificate authorities - accepted by the peer. Both arrays caNames, and caNameLens have this - many elements. */ - psSize_t nCas; +/* Misc. utility APIs. */ +PSPUBLIC psProtocolVersion_t matrixSslVersionFromMinorDigit( + uint16_t digit); +PSPUBLIC psX509Cert_t* sslKeysGetCACerts( + const sslKeys_t *keys); +PSPUBLIC char* matrixSslGetExpectedName( + const ssl_t *ssl); +PSPUBLIC sslKeys_t *matrixSslGetKeys( + ssl_t *ssl); +PSPUBLIC psBool_t matrixSslTlsVersionRangeSupported( + psProtocolVersion_t low, + psProtocolVersion_t high); -# if defined(USE_IDENTITY_CERTIFICATES) - /* Array of certificate authority names, binary DER encoding, as received - from the peer. Each element caNames[N] is a binary string whose lenght - is caNameLens[N] octets. - - These names can be memcmp()'d with values available from the - certificate subject/issuer names. */ - const unsigned char **caNames; - psSize_t *caNameLens; -# endif - - /* Supported signature algorithm masks for transport and - certificate chains (latter for TLS1.3) */ - uint32_t peerSigAlgMask; - uint32_t peerCertSigAlgMask; - - /* Algorithms supported by peer for session signature. The values are one - of SignatureAndHashAlgorithm for TLS12, and one of SignatureScheme - values for TLS13 The selected identity key needs to be usable for - producing authentication signature with this identified algoritm - combination. */ - psSize_t peerSigAlgsLen; - uint16_t peerSigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS]; - -#ifdef USE_TLS_1_3 - /* Algorithms supported by peer for certificate chains. If the session is - not TLS13 (or beyond), number of algorithms is always 0. */ - psSize_t peerCertSigAlgsLen; - uint16_t peerCertSigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS]; -#endif /* USE_TLS_1_3 */ -}; - - -/* Callback function with signature of sslIdentityCb will be caled from the - matrix library to obtain key material for TLS client authentication. The - 'ssl' identifies the handshake to authenticate, and 'keySpec' identifies - the key (type, certificate issuer) accepted by the peer. - - If this callback is set, it will be exclusively used for arranging - keys used for client authentication, regardless if identities - (keys) were provided when calling matrixSslNewClientSession(). - - The callback shall use function matrixSslSetClientIdentity() to - select the keys. - - The callback must return 0 on success and < 0 on failure (when key - or cert could not be loaded). -*/ -typedef int32_t (*sslIdentityCb_t)(struct ssl *ssl, - const sslKeySelectInfo_t *keySpec); - - - -/* Callback function of this type is called from the matrix library to report - each received TLS Hello Extension for the application */ -typedef int32_t (*sslExtCb_t)(struct ssl *ssl, uint16_t extType, uint8_t extLen, - void *e); - -#ifdef USE_CLIENT_SIDE_SSL /******************************************************************************/ -/* - Client side APIs - */ -/* Session ID management */ -PSPUBLIC int32 matrixSslNewSessionId(sslSessionId_t **sid, void *poolUserPtr); -PSPUBLIC void matrixSslClearSessionId(sslSessionId_t *sid); -PSPUBLIC void matrixSslDeleteSessionId(sslSessionId_t *sid); - -/* Create new client session into 'ssl'. 'keys' is cryptographic key - material, and certificates required for TLS client authentication, and TLS - server authentication. */ -PSPUBLIC int32_t matrixSslNewClientSession(ssl_t **ssl, - const sslKeys_t *keys, - sslSessionId_t *sid, - const psCipher16_t cipherSpec[], uint8_t cSpecLen, - sslCertCb_t certCb, - const char *expectedName, tlsExtension_t *extensions, - sslExtCb_t extCb, - sslSessOpts_t *options); /* Register a callback function called to select the client identity to be used for TLS client authentication of a session. If the 'identityCb' has been set, the identities provided via 'keys' argument for @@ -544,8 +378,9 @@ PSPUBLIC int32_t matrixSslNewClientSession(ssl_t **ssl, @param[in] ssl pointer to the session @param[in] identityCb callback function for identity selection */ -PSPUBLIC void matrixSslRegisterClientIdentityCallback(ssl_t *ssl, - sslIdentityCb_t identityCb); +PSPUBLIC void matrixSslRegisterClientIdentityCallback( + ssl_t *ssl, + sslIdentityCb_t identityCb); /* Use the 'keys' as a key-pair and certificate for the client identity for the TLS session. The matrix library will take a reference to the keys, and @@ -564,31 +399,12 @@ PSPUBLIC void matrixSslRegisterClientIdentityCallback(ssl_t *ssl, @param[in] ssl pointer to the session @param[in] keys selected for client authentication (may be NULL). */ -PSPUBLIC psBool_t matrixSslSetClientIdentity(ssl_t *ssl, - const sslKeys_t *keys); +PSPUBLIC psBool_t matrixSslSetClientIdentity( + ssl_t *ssl, + const sslKeys_t *keys); -/* Hello extension support. RFC 3546 */ -PSPUBLIC int32 matrixSslNewHelloExtension(tlsExtension_t **extension, - void *poolUserPtr); -PSPUBLIC int32 matrixSslLoadHelloExtension(tlsExtension_t *extension, - unsigned char *extData, uint32 length, - uint32 extType); -PSPUBLIC void matrixSslDeleteHelloExtension(tlsExtension_t *extension); -PSPUBLIC int32 matrixSslCreateSNIext(psPool_t *pool, unsigned char *host, - int32 hostLen, unsigned char **extOut, int32 *extLen); -PSPUBLIC int32_t matrixSslSessOptsSetClientTlsVersionRange(sslSessOpts_t *options, - psProtocolVersion_t low, - psProtocolVersion_t high); -PSPUBLIC int32_t matrixSslSessOptsSetClientTlsVersions(sslSessOpts_t *options, - const psProtocolVersion_t versions[], - int32_t versionsLen); - -# ifdef USE_ALPN -PSPUBLIC int32 matrixSslCreateALPNext(psPool_t *pool, int32 protoCount, - unsigned char *proto[], int32 protoLen[], - unsigned char **extOut, int32 *extLen); -# endif # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING +# include "psExt.h" /** Enable external signing for the CertificateVerify message. This function is used to turn on the USE_EXT_CERTIFICATE_SIGNING feature @@ -738,238 +554,60 @@ PSPUBLIC psBool_t matrixSslClientCertUpdated(ssl_t *ssl); PSPUBLIC psBool_t matrixSslClientPrivKeyUpdated(ssl_t *ssl); #endif /* USE_EXT_CLIENT_CERT_KEY_LOADING */ -# endif /* USE_CLIENT_SIDE_SSL */ -/******************************************************************************/ -# ifdef USE_SERVER_SIDE_SSL -/******************************************************************************/ -/* - Server side APIs - */ -PSPUBLIC int32_t matrixSslNewServerSession(ssl_t **ssl, - const sslKeys_t *keys, - sslCertCb_t certCb, - sslSessOpts_t *options); - - -/* sslPubkeyId_t structure is given as a key selector to pubkeyCB_t type - function used for selecting the identity key pair for the SSL server. */ -typedef struct -{ - unsigned short keyType; - unsigned short hashAlg; - unsigned short curveFlags; - unsigned short dhParamsRequired; - /* Name of the (virtual)server the peer connected to. The pubkeyCb should - return a certificate having this name as its subject name CN, or as a - subjectAltName. */ - char *serverName; -} sslPubkeyId_t; - -/* A callback function of type pubkeyCb_t is called from the library on the - TLS server side to retrieve a keypair to use for server authentication for - the connection described by 'ssl' using algoritms specified by 'keyId'. - - This callback is not called, if the server side session was created using - matrixSslNewServerSession() and the server identity keys were already - provided during that call. - - This callback may be called multiple times with different 'keyId' (key - types in particular) for each 'ssl' connection. The callback is not called - for the same session after it has returned non-null value (found usable - keypair). - - The function shall return a sslKeys_t instance, or a NULL pointer in case - suitable keys are not found. */ -typedef sslKeys_t *(*pubkeyCb_t)(struct ssl *ssl, const sslPubkeyId_t *keyId); - -/* A callback function of the pskCb_t is called from the library to retrieve - shared secret corresponding to the pskId from the application key - storage. The application returns returns PS_SUCCESS and fills in the key - into psk, and key length into pskLen if the key corresponding to the given - pskId is found. If key is not found, a negative error code shall be - returned resulting into aborted handshake. */ -typedef int32_t (*pskCb_t)(struct ssl *ssl, - const unsigned char pskId[SSL_PSK_MAX_ID_SIZE], - uint8_t pskIdLen, - unsigned char *psk[SSL_PSK_MAX_KEY_SIZE], - uint8_t *pskLen); - -PSPUBLIC int32_t matrixSslNewServer(ssl_t **ssl, - pubkeyCb_t pubkeyCb, - pskCb_t pskCb, - sslCertCb_t certCb, - sslSessOpts_t *options); -PSPUBLIC int32 matrixSslSetCipherSuiteEnabledStatus(ssl_t *ssl, - psCipher16_t cipherId, - uint32 status); - -# ifdef USE_SEC_CONFIG -/** Security operation IDs. */ -typedef enum -{ - secop_undefined = 0, - secop_symmetric_encrypt, - secop_hmac, - secop_hash_for_sig, - secop_rsa_encrypt, - secop_rsa_decrypt, - secop_rsa_sign, - secop_rsa_verify, - secop_rsa_load_key, - secop_ecdsa_sign, - secop_ecdsa_verify, - secop_ecdsa_load_key, - secop_dh_import_pub, - secop_ecdh_import_pub, - secop_proto_version_check, - secop_sigalg_check, - secop_cipher_check -} psSecOperation_t; -/** Security callback. - This function will be called by MatrixSSL or Matrix Crypto to query - the permissibility of an operation. */ -typedef psRes_t (*securityCb_t)( - void *ctx, /* Pointer to either ssl_t or crypto_t */ - psSecOperation_t op, /* Crypto/TLS op code, e.g. CRYPTO_OP_RSA_PKCS1_5_SIGN. */ - psSizeL_t nbits, /* Bits to use in the operation (key size or similar.) */ - void *extraData); /* Extra decision-making info; format depends on op. */ -/** Set the security callback to use in TLS connections using ssl_t. */ -void matrixSslRegisterSecurityCallback( - ssl_t *ssl, - securityCb_t cb); -/** Pre-defined security profiles. */ -typedef enum -{ - secprofile_default = 0, - secprofile_wpa3_1_0_enterprise_192 = 1 -} psPreDefinedSecProfile_t; -/** Assign one of the pre-defined security profiles to ssl struct. */ -PSPUBLIC int32_t matrixSslSetSecurityProfile( - ssl_t *ssl, - psPreDefinedSecProfile_t profile); -# endif /* USE_SEC_CONFIG */ - -PSPUBLIC int32_t matrixSslSessOptsSetServerTlsVersionRange( - sslSessOpts_t *options, - psProtocolVersion_t low, - psProtocolVersion_t high); -PSPUBLIC int32_t matrixSslSessOptsSetServerTlsVersions( - sslSessOpts_t *options, - const psProtocolVersion_t versions[], - int32_t versionsLen); - -/* Callback function of this type is called from the matrix library on the - server side to retrieve server Identity Keys corresponding to the virtual - hostname received from the TLS ServerNameIndication. The callback shall - fill into newKeys the key material to use. The provided key material, if - any, shall be allocated using matrixSslNewKeys(), and the matrix library - will take care of freeing the keys when they are no longer needed. - - Note, that if both sniCb and pubkeyCb have been set, and sniCb provides key - material, the pubkeyCb will not be called. */ - -typedef void (*sniCb_t)(void *ssl, - char *hostname, int32 hostnameLen, - sslKeys_t **newKeys); - - -PSPUBLIC void matrixSslRegisterSNICallback(ssl_t *ssl, sniCb_t sni_cb); - -# ifdef USE_ALPN -PSPUBLIC void matrixSslRegisterALPNCallback(ssl_t *ssl, - void (*srv_alpn_cb)(void *ssl, short protoCount, - char *proto[MAX_PROTO_EXT], int32 protoLen[MAX_PROTO_EXT], - int32 *index)); -# endif - -# ifdef USE_STATELESS_SESSION_TICKETS -PSPUBLIC void matrixSslSetSessionTicketCallback(sslKeys_t *keys, - int32 (*ticket_cb)(void *, unsigned char[16], short)); -PSPUBLIC int32 matrixSslLoadSessionTicketKeys(sslKeys_t *keys, - const unsigned char name[16], const unsigned char *symkey, - short symkeyLen, const unsigned char *hashkey, short hashkeyLen); -PSPUBLIC int32 matrixSslDeleteSessionTicketKey(sslKeys_t * keys, - unsigned char name[16]); -# endif -# endif /* USE_SERVER_SIDE_SSL */ - - -/******************************************************************************/ -/* - Advanced feature public APIS - */ -PSPUBLIC void matrixSslGetAnonStatus(ssl_t *ssl, int32 *anonArg); -PSPUBLIC int32_t matrixSslEncodeRehandshake(ssl_t *ssl, sslKeys_t *keys, - sslCertCb_t certCb, - uint32_t sessionOption, - const psCipher16_t cipherSpec[], uint8_t cSpecLen); -PSPUBLIC int32 matrixSslDisableRehandshakes(ssl_t *ssl); -PSPUBLIC int32 matrixSslReEnableRehandshakes(ssl_t *ssl); - - - -# ifdef USE_DTLS -/******************************************************************************/ -/* - DTLS - */ -PSPUBLIC int32 matrixDtlsSentData(ssl_t *ssl, uint32 bytes); -PSPUBLIC int32 matrixDtlsGetOutdata(ssl_t *ssl, unsigned char **buf); -PSPUBLIC int32 matrixDtlsSetPmtu(int32 pmtu); -PSPUBLIC int32 matrixDtlsGetPmtu(void); -# endif /* USE_DTLS */ -/******************************************************************************/ - -# ifdef REQUIRE_DH_PARAMS -/******************************************************************************/ -/* - Diffie-Helloman - */ -PSPUBLIC int32 matrixSslLoadDhParams(sslKeys_t *keys, const char *paramFile); -PSPUBLIC int32 matrixSslLoadDhParamsMem(sslKeys_t *keys, - const unsigned char *dhBin, int32 dhBinLen); -# endif /* REQUIRE_DH_PARAMS */ -/******************************************************************************/ - -# ifdef USE_PSK_CIPHER_SUITE -/******************************************************************************/ -/* - Pre-shared Keys - */ -PSPUBLIC int32_t matrixSslLoadPsk(sslKeys_t *keys, - const unsigned char key[SSL_PSK_MAX_KEY_SIZE], - uint8_t keyLen, - const unsigned char id[SSL_PSK_MAX_ID_SIZE], - uint8_t idLen); -# ifdef USE_TLS_1_3 -PSPUBLIC int32_t matrixSslLoadTls13Psk(sslKeys_t *keys, - const unsigned char *key, - psSize_t keyLen, - const unsigned char *id, - psSize_t idLen, - const psTls13SessionParams_t *params); -# endif /* USE_TLS_1_3 */ -# endif /* USE_PSK_CIPHER_SUITE */ -/******************************************************************************/ - -# ifdef USE_ECC -/******************************************************************************/ -/* - Elliptic Curve Suites - */ -PSPUBLIC int32 matrixSslLoadEcKeys(sslKeys_t *keys, +/* Algorithm-specific key loading functions. */ +PSPUBLIC int32 matrixSslLoadDhParams( + sslKeys_t *keys, + const char *paramFile); +PSPUBLIC int32 matrixSslLoadDhParamsMem( + sslKeys_t *keys, + const unsigned char *dhBin, + int32 dhBinLen); +PSPUBLIC int32 matrixSslLoadRsaKeysExt( + sslKeys_t *keys, + const char *certFile, + const char *privFile, + const char *privPass, + const char *trustedCAFile, + matrixSslLoadKeysOpts_t *opts); +PSPUBLIC int32 matrixSslLoadRsaKeys( + sslKeys_t *keys, + const char *certFile, + const char *privFile, + const char *privPass, + const char *trustedCAFile); +PSPUBLIC int32 matrixSslLoadRsaKeysMemExt( + sslKeys_t *keys, + const unsigned char *certBuf, + int32 certLen, + const unsigned char *privBuf, + int32 privLen, + const unsigned char *trustedCABuf, + int32 trustedCALen, + matrixSslLoadKeysOpts_t *opts); +PSPUBLIC int32 matrixSslLoadRsaKeysMem( + sslKeys_t *keys, + const unsigned char *certBuf, + int32 certLen, + const unsigned char *privBuf, + int32 privLen, + const unsigned char *trustedCABuf, + int32 trustedCALen); +PSPUBLIC int32 matrixSslLoadEcKeys( + sslKeys_t *keys, const char *certFile, const char *privFile, const char *privPass, const char *CAfile); -PSPUBLIC int32 matrixSslLoadEcKeysExt(sslKeys_t *keys, +PSPUBLIC int32 matrixSslLoadEcKeysExt( + sslKeys_t *keys, const char *certFile, const char *privFile, const char *privPass, const char *CAfile, matrixSslLoadKeysOpts_t *opts); -PSPUBLIC int32 matrixSslLoadEcKeysMemExt(sslKeys_t *keys, +PSPUBLIC int32 matrixSslLoadEcKeysMemExt( + sslKeys_t *keys, const unsigned char *certBuf, int32 certLen, const unsigned char *privBuf, @@ -977,44 +615,14 @@ PSPUBLIC int32 matrixSslLoadEcKeysMemExt(sslKeys_t *keys, const unsigned char *CAbuf, int32 CAlen, matrixSslLoadKeysOpts_t *opts); -PSPUBLIC int32 matrixSslLoadEcKeysMem(sslKeys_t *keys, +PSPUBLIC int32 matrixSslLoadEcKeysMem( + sslKeys_t *keys, const unsigned char *certBuf, int32 certLen, const unsigned char *privBuf, int32 privLen, const unsigned char *CAbuf, int32 CAlen); -# ifdef USE_ECC -PSPUBLIC int32_t matrixSslGenEphemeralEcKey(sslKeys_t *keys, - psEccKey_t *ecc, - const psEccCurve_t *curve, - void *hwCtx); -# endif -# endif /* USE_ECC */ - -/******************************************************************************/ - -# ifdef USE_MATRIXSSL_STATS - -enum -{ - STAT_CH_RECV = 1, /**< Count of ClientHellos recvd */ - STAT_CH_SENT, /**< Count of ClientHellos sent */ - STAT_SH_RECV, /**< Count of ServerHellos recvd */ - STAT_SH_SENT, /**< Count of ServerHellos sent */ - STAT_ALERT_SENT, /**< Count of Alerts sent */ - STAT_RESUMPTIONS, /**< Count of Resumptions */ - STAT_FAILED_RESUMPTIONS, /**< Count of attempted but rejected resumptions */ - STAT_APP_DATA_RECV, /**< Bytes of encoded appdata received (incl hdr/mac) */ - STAT_APP_DATA_SENT, /**< Bytes of encoded appdata sent (incl hdr/mac) */ - STAT_PT_DATA_RECV, /**< Bytes of plaintext appdata received */ -}; - -PSPUBLIC void matrixSslRegisterStatCallback(ssl_t *ssl, - void (*stat_cb)(void *ssl, void *stat_ptr, int32 type, int32 value), - void *stats); - -# endif # ifdef __cplusplus } @@ -1022,10 +630,6 @@ PSPUBLIC void matrixSslRegisterStatCallback(ssl_t *ssl, /******************************************************************************/ -/* The internal header still needs to be included for compatibility, as some - "applications" access internal data types directly. */ -# include "matrixssllib.h" - #endif /* _h_MATRIXSSL */ /******************************************************************************/ diff --git a/matrixssl/matrixsslApiAlert.h b/matrixssl/matrixsslApiAlert.h new file mode 100644 index 0000000..533db42 --- /dev/null +++ b/matrixssl/matrixsslApiAlert.h @@ -0,0 +1,81 @@ +/** + * @file matrixsslApiTls.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains alert constants. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_ALERT +# define _h_MATRIXSSL_API_ALERT + +# define SSL_ALERT_LEVEL_WARNING 1 +# define SSL_ALERT_LEVEL_FATAL 2 + +# define SSL_ALERT_CLOSE_NOTIFY 0 +# define SSL_ALERT_UNEXPECTED_MESSAGE 10 +# define SSL_ALERT_BAD_RECORD_MAC 20 +# define SSL_ALERT_DECRYPTION_FAILED 21/* Do not use, per RFC 5246 */ +# define SSL_ALERT_RECORD_OVERFLOW 22 +# define SSL_ALERT_DECOMPRESSION_FAILURE 30 +# define SSL_ALERT_HANDSHAKE_FAILURE 40 +# define SSL_ALERT_NO_CERTIFICATE 41 +# define SSL_ALERT_BAD_CERTIFICATE 42 +# define SSL_ALERT_UNSUPPORTED_CERTIFICATE 43 +# define SSL_ALERT_CERTIFICATE_REVOKED 44 +# define SSL_ALERT_CERTIFICATE_EXPIRED 45 +# define SSL_ALERT_CERTIFICATE_UNKNOWN 46 +# define SSL_ALERT_ILLEGAL_PARAMETER 47 +# define SSL_ALERT_UNKNOWN_CA 48 +# define SSL_ALERT_ACCESS_DENIED 49 +# define SSL_ALERT_DECODE_ERROR 50 +# define SSL_ALERT_DECRYPT_ERROR 51 +# define SSL_ALERT_PROTOCOL_VERSION 70 +# define SSL_ALERT_INSUFFICIENT_SECURITY 71 +# define SSL_ALERT_INTERNAL_ERROR 80 +# define SSL_ALERT_INAPPROPRIATE_FALLBACK 86 +# define SSL_ALERT_NO_RENEGOTIATION 100 +# define SSL_ALERT_UNSUPPORTED_EXTENSION 110 +# define SSL_ALERT_UNRECOGNIZED_NAME 112 +# define SSL_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define SSL_ALERT_UNKNOWN_PSK_IDENTITY 115 +# define SSL_ALERT_NO_APP_PROTOCOL 120 + +/* Additional ssl alert value, indicating no error has ocurred. */ +# define SSL_ALERT_NONE 255/* No error */ + +/* + Use as return code in user validation callback to allow + anonymous connections to proceed. + MUST NOT OVERLAP WITH ANY OF THE ALERT CODES ABOVE + */ +# define SSL_ALLOW_ANON_CONNECTION 254 + +#endif diff --git a/matrixssl/matrixsslApiCipher.h b/matrixssl/matrixsslApiCipher.h new file mode 100644 index 0000000..cb95340 --- /dev/null +++ b/matrixssl/matrixsslApiCipher.h @@ -0,0 +1,109 @@ +/** + * @file matrixsslApiCipher.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains ciphersuite IDs. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_CIPHER +# define _h_MATRIXSSL_API_CIPHER + +/* Cipher suite specification IDs, in numerical order. */ +# define SSL_NULL_WITH_NULL_NULL 0x0000 +# define SSL_RSA_WITH_NULL_MD5 0x0001 +# define SSL_RSA_WITH_NULL_SHA 0x0002 +# define SSL_RSA_WITH_RC4_128_MD5 0x0004 +# define SSL_RSA_WITH_RC4_128_SHA 0x0005 +# define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007 +# define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000A /* 10 */ +# define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 /* 22 */ +# define SSL_DH_anon_WITH_RC4_128_MD5 0x0018 /* 24 */ +# define SSL_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B /* 27 */ +# define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F /* 47 */ +# define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 /* 51 */ +# define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 /* 52 */ +# define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 /* 53 */ +# define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 /* 57 */ +# define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A /* 58 */ +# define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C /* 60 */ +# define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D /* 61 */ +# define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 /* 103 */ +# define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B /* 107 */ +# define TLS_RSA_WITH_SEED_CBC_SHA 0x0096 /* 150 */ +# define TLS_PSK_WITH_AES_128_CBC_SHA 0x008C /* 140 */ +# define TLS_PSK_WITH_AES_128_CBC_SHA256 0x00AE /* 174 */ +# define TLS_PSK_WITH_AES_256_CBC_SHA384 0x00AF /* 175 */ +# define TLS_PSK_WITH_AES_256_CBC_SHA 0x008D /* 141 */ +# define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x0090 /* 144 */ +# define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x0091 /* 145 */ +# define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C /* 156 */ +# define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D /* 157 */ +# define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F /* 159 */ + +# define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF /**< @see RFC 5746 */ +# define TLS_FALLBACK_SCSV 0x5600 /**< @see RFC 7507 */ + +# define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /* 49156 */ +# define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /* 49157 */ +# define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /* 49161 */ +# define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /* 49162 */ +# define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /* 49170 */ +# define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /* 49171 */ +# define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /* 49172 */ +# define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /* 49166 */ +# define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /* 49167 */ +# define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /* 49187 */ +# define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /* 49188 */ +# define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /* 49189 */ +# define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /* 49190 */ +# define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /* 49191 */ +# define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /* 49192 */ +# define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /* 49193 */ +# define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /* 49194 */ +# define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /* 49195 */ +# define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /* 49196 */ +# define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /* 49197 */ +# define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /* 49198 */ +# define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /* 49199 */ +# define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /* 49200 */ +# define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /* 49201 */ +# define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /* 49202 */ +/* Defined in https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305 */ +# define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /* 52392 */ +# define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /* 52393 */ +/* TLS 1.3 ciphersuites. */ +# define TLS_AES_128_GCM_SHA256 0x1301 /* 4865 */ +# define TLS_AES_256_GCM_SHA384 0x1302 /* 4866 */ +# define TLS_CHACHA20_POLY1305_SHA256 0x1303 /* 4867 */ +# define TLS_AES_128_CCM_SHA_256 0x1304 /* 4868 */ +# define TLS_AES_128_CCM_8_SHA256 0x1305 /* 4869 */ + +#endif diff --git a/matrixssl/matrixsslApiExt.h b/matrixssl/matrixsslApiExt.h new file mode 100644 index 0000000..635ad69 --- /dev/null +++ b/matrixssl/matrixsslApiExt.h @@ -0,0 +1,67 @@ +/** + * @file matrixsslApiExt.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains TLS extension IDs. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_EXT +# define _h_MATRIXSSL_API_EXT + +/* IANA numbers for supported TLS extensions. */ +# define EXT_SNI 0 +# define EXT_SERVER_NAME 0 /* SNI renamed in TLS 1.3 */ +# define EXT_MAX_FRAGMENT_LEN 1 +# define EXT_TRUSTED_CA_KEYS 3 +# define EXT_TRUNCATED_HMAC 4 +# define EXT_STATUS_REQUEST 5 /* OCSP */ +# define EXT_ELLIPTIC_CURVE 10 /* Client-send only */ +# define EXT_SUPPORTED_GROUPS 10 /* ELLIPTIC_CURVE renamed in 1.3 */ +# define EXT_ELLIPTIC_POINTS 11 +# define EXT_SIGNATURE_ALGORITHMS 13 +# define EXT_ALPN 16 +# define EXT_SIGNED_CERTIFICATE_TIMESTAMP 18 +# define EXT_EXTENDED_MASTER_SECRET 23 +# define EXT_SESSION_TICKET 35 +# define EXT_KEY_SHARE_PRE_DRAFT_23 40 /* Up to 1.3 draft 22 */ +# define EXT_PRE_SHARED_KEY 41 +# define EXT_EARLY_DATA 42 +# define EXT_SUPPORTED_VERSIONS 43 +# define EXT_COOKIE 44 +# define EXT_PSK_KEY_EXCHANGE_MODES 45 +# define EXT_CERTIFICATE_AUTHORITIES 47 +# define EXT_OID_FILTERS 48 +# define EXT_POST_HANDSHAKE_AUTH 49 +# define EXT_SIGNATURE_ALGORITHMS_CERT 50 +# define EXT_KEY_SHARE 51 /* Since 1.3 draft 23. */ +# define EXT_RENEGOTIATION_INFO 0xFF01 + +#endif diff --git a/matrixssl/matrixsslApiLimits.h b/matrixssl/matrixsslApiLimits.h new file mode 100644 index 0000000..1e9f21f --- /dev/null +++ b/matrixssl/matrixsslApiLimits.h @@ -0,0 +1,117 @@ +/** + * @file matrixsslApiLimits.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains minimum and maximum + * buffer size and other limits. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_LIMITS +# define _h_MATRIXSSL_API_LIMITS + +/* Maximum SSL/TLS record size, per specification. */ +# define SSL_MAX_PLAINTEXT_LEN 0x4000 /* 16KB */ +# define SSL_MAX_RECORD_LEN SSL_MAX_PLAINTEXT_LEN + 2048 +# define SSL_MAX_BUF_SIZE 0xffff /* 65536. This must be enough for + entire outgoing flight */ +/* + From section 5.2. of the TLS 1.3 spec. + Assuming a fullsize TLSPlaintext.fragment, TLSInnerPlaintext adds + 1 type octet and TLSCiphertext adds at most 255 AEAD overhead. +*/ +# define TLS_1_3_MAX_PLAINTEXT_FRAGMENT_LEN 16384 /* 2^14 */ +# define TLS_1_3_MAX_INNER_PLAINTEXT_LEN 16385 /* 2^14 + 1 */ +# define TLS_1_3_MAX_CIPHERTEXT_LEN 16640 /* 2^14 + 1 + 255 */ + +/* + Maximum buffer sizes for static SSL array types + */ +# define SSL_MAX_MAC_SIZE 48/* SHA384 */ +# define SSL_MAX_IV_SIZE 16 +# define SSL_MAX_BLOCK_SIZE 16 +# define SSL_MAX_SYM_KEY_SIZE 32 +# define MAX_TLS_1_3_HASH_SIZE SHA384_HASHLEN + +/* Maximum number of simultaneous TLS versions supported */ +# define TLS_MAX_SUPPORTED_VERSIONS 16 +/* TLS 1.3: maximum number of algorithms in signature_algorithms extension. */ +# define TLS_MAX_SIGNATURE_ALGORITHMS 32 +/* TLS 1.3: maximum number of cipher suites to support in clientHello */ +# define TLS_1_3_MAX_CIPHER_SUITES 8 +/* TLS 1.3: maximum number of groups. */ +# define TLS_1_3_MAX_GROUPS 32 + +/* Maximum number of compiled-in ciphers that can be disabled + at run-time using the matrixSslSetCiphersuiteEnabledStatus API. */ +# define SSL_MAX_DISABLED_CIPHERS 32 + +/* + TLS implementations supporting these ciphersuites MUST support + arbitrary PSK identities up to 128 octets in length, and arbitrary + PSKs up to 64 octets in length. Supporting longer identities and + keys is RECOMMENDED. + */ +# define SSL_PSK_MAX_KEY_SIZE 64 /* Must be < 256 due to 'idLen' */ +# define SSL_PSK_MAX_ID_SIZE 128 /* Must be < 256 due to 'idLen' */ +# define SSL_PSK_MAX_HINT_SIZE 32 /* ServerKeyExchange hint is non-standard */ + +/* How large the ALPN extension arrary is. Number of protos client can talk */ +# define MAX_PROTO_EXT 8 + +/* + Maximum key block size for any defined cipher + This must be validated if new ciphers are added + Value is largest total among all cipher suites for + 2*macSize + 2*keySize + 2*ivSize + Rounded up to nearest PRF block length. We aren't really + rounding, but just adding another block length for simplicity. + */ +# ifdef USE_TLS_1_2 +# define SSL_MAX_KEY_BLOCK_SIZE ((2 * 48) + (2 * 32) + (2 * 16) + SHA256_HASH_SIZE) +# else +# define SSL_MAX_KEY_BLOCK_SIZE ((2 * 48) + (2 * 32) + (2 * 16) + SHA1_HASH_SIZE) +# endif +# ifdef USE_EAP_FAST +# define EAP_FAST_SESSION_KEY_SEED_LEN 40 +# define EAP_FAST_PAC_KEY_LEN 32 +# undef SSL_MAX_KEY_BLOCK_SIZE +# define SSL_MAX_KEY_BLOCK_SIZE ((2 * 48) + (2 * 32) + (2 * 16) + \ + SHA256_HASH_SIZE + \ + EAP_FAST_SESSION_KEY_SEED_LEN) +# endif + +/* + Master secret is 48 bytes, sessionId is 32 bytes max + */ +# define SSL_HS_MASTER_SIZE 48 +# define SSL_MAX_SESSION_ID_SIZE 32 + +#endif diff --git a/matrixssl/matrixsslApiPre.h b/matrixssl/matrixsslApiPre.h new file mode 100644 index 0000000..bffbeec --- /dev/null +++ b/matrixssl/matrixsslApiPre.h @@ -0,0 +1,69 @@ +/** + * @file matrixsslApiVer.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains protocol version related + * defines. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_PRE +# define _h_MATRIXSSL_API_PRE + +# include "coreApi.h" /* cryptoApi.h and matrixsslApi.h depend on this */ +# include "../crypto/cryptoApi.h" /* matrixsslApi.h depend on cryptoApi.h. */ + +# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST +# include /* Get matrixssl configuration from -I dir. */ +# else +# include "matrixsslConfig.h" /* Get local matrixssl configuration file. */ +# endif + +# ifdef DISABLE_TLS_1_3 +# undef USE_TLS_1_3 +# undef USE_TLS_AES_128_GCM_SHA256 +# undef USE_TLS_AES_256_GCM_SHA384 +# undef USE_TLS_CHACHA20_POLY1305_SHA256 +# endif + +# include "version.h" + +/* + Build the configuration string with the relevant build options for + runtime validation of compile-time configuration. + */ +# define HW_CONFIG_STR "N" + +# define MATRIXSSL_CONFIG \ + "Y" \ + HW_CONFIG_STR \ + PSCRYPTO_CONFIG + +#endif diff --git a/matrixssl/matrixsslApiRet.h b/matrixssl/matrixsslApiRet.h new file mode 100644 index 0000000..7480343 --- /dev/null +++ b/matrixssl/matrixsslApiRet.h @@ -0,0 +1,72 @@ +/** + * @file matrixsslApiVer.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains return codes. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_RET +# define _h_MATRIXSSL_API_RET + +/* Main matrixSsl* API return codes. */ +# define MATRIXSSL_SUCCESS PS_SUCCESS /* Generic success */ +# define MATRIXSSL_ERROR PS_PROTOCOL_FAIL /* Generic SSL error */ +# define MATRIXSSL_REQUEST_SEND 1 /* API produced data to be sent */ +# define MATRIXSSL_REQUEST_RECV 2 /* API requres more data to continue */ +# define MATRIXSSL_REQUEST_CLOSE 3 /* API indicates clean close is req'd */ +# define MATRIXSSL_APP_DATA 4 /* App data is avail. to caller */ +# define MATRIXSSL_HANDSHAKE_COMPLETE 5 /* Handshake completed */ +# define MATRIXSSL_RECEIVED_ALERT 6 /* An alert was received */ +# define MATRIXSSL_APP_DATA_COMPRESSED 7 /* App data must be inflated */ + +/* TLS 1.3 specific return codes. */ +# define MATRIXSSL_EARLY_DATA_ACCEPTED 8 +# define MATRIXSSL_EARLY_DATA_REJECTED 9 +# define MATRIXSSL_EARLY_DATA_SENT 10 +# define MATRIXSSL_EARLY_DATA_NOT_SENT 11 + +/* Negative return codes must be between -50 and -69 in the MatrixSSL module */ +# define SSL_FULL -50 /* must call sslRead before decoding */ +# define SSL_PARTIAL -51 /* more data reqired to parse full msg */ +# define SSL_SEND_RESPONSE -52 /* decode produced output data */ +# define SSL_PROCESS_DATA -53 /* succesfully decoded application data */ +# define SSL_ALERT -54 /* we've decoded an alert */ +# define SSL_FILE_NOT_FOUND -55 /* File not found */ +# define SSL_MEM_ERROR PS_MEM_FAIL /* Memory allocation failure */ +# ifdef USE_DTLS +# define DTLS_MUST_FRAG -60 /* Message must be fragmented */ +# define DTLS_RETRANSMIT -61/* Received a duplicate hs msg from peer */ +# endif /* USE_DTLS */ +# define SSL_ENCODE_RESPONSE -62 /* Need to encode a response. */ +# define SSL_NO_TLS_1_3 -63 /* We advertised TLS 1.3, but server + chose TLS <1.3. */ + +#endif diff --git a/matrixssl/matrixsslApiTypes.h b/matrixssl/matrixsslApiTypes.h new file mode 100644 index 0000000..2c0e24e --- /dev/null +++ b/matrixssl/matrixsslApiTypes.h @@ -0,0 +1,414 @@ +/** + * @file matrixsslApiTypes.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains type definitions + * needed when using the matrixSsl* API. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_TYPES +# define _h_MATRIXSSL_API_TYPES + +/* Forward declarations for opaque types. */ +typedef struct ssl ssl_t; +typedef struct sslKeys sslKeys_t; +typedef struct tlsExtension tlsExtension_t; +typedef struct sslSessionId sslSessionId_t; +typedef struct psTls13SessionParams psTls13SessionParams_t; +typedef struct psTls13Psk psTls13Psk_t; +typedef struct psOcspResponse psOcspResponse_t; + +/** Type of the expectedName parameter (expected peer identity) + that is passed to matrixValidateCerts or matrixSslNewClientSession. + These can be used to specify the field in the peer certificate + against which expectedName is to be matched. */ +typedef enum +{ + NAME_TYPE_ANY = 0, /* Default. Checked against everything listed below. + This option exists for compatibility with earlier + versions, where no attempt was made to distinguish + between different types of expectedNames. + New applications should prefer to pick one of the + more specific types below. */ + NAME_TYPE_HOSTNAME, /* Checked against the dNSName field and the + subject commonName. This is the default. */ + NAME_TYPE_CN, /* Checked against the subject commonName. + Note that by default, the subject commonName will only + be checked when there are no supported fields + in the SAN. The flag + VCERTS_MFLAG_ALWAYS_CHECK_SUBJECT_CN can be used + to force a commonName check. */ + NAME_TYPE_SAN_DNS, /* Checked against the dNSName field. */ + NAME_TYPE_SAN_EMAIL, /* Checked against the rfc822Name field. */ + NAME_TYPE_SAN_IP_ADDRESS, /* Checked against the iPAddress field. */ +} expectedNameType_t; + +/* flags for matrixValidateCertsOptions_t: */ +/** + Validate the expectedName argument against a subset of the + GeneralName rules for DNS, Email and IP types _before_ trying + to find for expectedName in the cert. Note that this is only + applicable if expectedName is a GeneralName, i.e. when using + any of the VCERTS_MFLAG_SAN flags. + */ +# define VCERTS_FLAG_VALIDATE_EXPECTED_GENERAL_NAME 0x01 + +/** + Skip the expectedName matching. This is useful e.g. when + matrixValidateCerts is called by the TLS server to validate + a client certificate. The client name is usually not known + in this case. + */ +# define VCERTS_FLAG_SKIP_EXPECTED_NAME_VALIDATION 0x02 + +/** + Enable matrixValidateCertsExt to perform an independent validation + of the certificate date ranges. Dates of the subject cert chain + and the found issuer cert are validated against the current + system time. + + By default, MatrixSSL only checks the certificate date validity + during certificate parsing, setting the PS_CERT_AUTH_FAIL_DATE_FLAG + flag in cert->authFailFlags when date validation fails. This flag + will be noticed by matrixValidateCertsExt (but only for subject + certs, not the found issuer cert). In some applications, the delay + between parsing and the actual chain validation can be long. In such + situations, it is useful to re-perform the date validation + in matrixValidateCertsExt. +*/ +# define VCERTS_FLAG_REVALIDATE_DATES 0x04 + +/* mFlags for matrixValidateCertsOptions_t: */ +/** + If expectedName is a hostname, always attempt to match it + with the subject CN, even if a supported, but non-matching + subjectAltName was presented. + Without this flag, the CN is checked only when no supported SAN + was presented. This default behaviour is in accordance with + Section 6.4.4 of RFC 6125, and this flag overrides it. + */ +# define VCERTS_MFLAG_ALWAYS_CHECK_SUBJECT_CN 0x01 + +/** + Use case-insensitive match for the the whole email address + in the rfc822Name field of the SAN. Without this flag, + case-sensitive matching is used for the local-part and + case-insensitive matching for the host-part, in accordance + with RFC 5280. + This flag requires VCERTS_MFLAG_SAN_MATCH_RFC822NAME. + */ +# define VCERTS_MFLAG_SAN_EMAIL_CASE_INSENSITIVE_LOCAL_PART 0x02 + +/** Certificate validation options. */ +typedef struct +{ + expectedNameType_t nameType; /* Type of expectedName. */ + uint64_t flags; /* General flags for controling the validation + prodecure. The allowed flags have the + VCERTS_FLAG_ prefix. */ + uint32_t mFlags; /* Flags for controlling how expectedName should + be matched. The allowed flags have the + USE VCERTS_MFLAG prefix. */ + int32_t max_verify_depth; /* Maximum allowed depth for the peer's + cert chain. 0 : unrestricted, + 1: only a single (self-signed) cert allowed, + 2: peer cert + 1 root CA + 3: peer cert + 1 CA + 1 root CA, etc. */ +} matrixValidateCertsOptions_t; + +/** sslSessOpts_t: session options. A pointer to this struct is passed + to matrixSslNewServerSession and matrixSslNewClientSession. + This struct should be accessed using the matrixSslSessOpts* API + when possible. */ +typedef struct +{ + /* Priority list of supported protocol versions*/ + uint32_t supportedVersions[TLS_MAX_SUPPORTED_VERSIONS]; + psSize_t supportedVersionsLen; + /* Client: 1 to send status_request */ + short OCSPstapling; + /* Elliptic curve set (SSL_OPT_SECP192R1 etc.) */ + int32 ecFlags; + /* Client: sign the handshake messages hash in CertificateVerify + using the external security token API. */ + int32 useExtCvSigOp; + uint16_t tls13SupportedSigAlgsCert[TLS_MAX_SIGNATURE_ALGORITHMS]; + psSize_t tls13SupportedSigAlgsCertLen; + /* For server this defines what is the max early data value for the + new session tickets. Not used for clients. */ + psSize_t tls13SessionMaxEarlyData; + /* Initial value of ssl->userPtr during NewSession */ + void *userPtr; + /* Will be passed to psOpenPool for each call related to this session */ + void *memAllocPtr; + /* Optional mem pool for inbuf and outbuf */ + psPool_t *bufferPool; + /* Keep raw DER of peer certs */ + int32 keep_peer_cert_der; + /* Keep peer cert chain until the session is deleted */ + int32 keep_peer_certs; + /* Certificate validation options. */ + matrixValidateCertsOptions_t validateCertsOpts; + /* Initial value of ssl->userDataPtr during NewSession. */ + void *userDataPtr; + /* List of key exchange groups to support. */ + uint16_t tls13SupportedGroups[TLS_1_3_MAX_GROUPS]; + psSize_t tls13SupportedGroupsLen; + /* Number of key shares to send in TLS 1.3 ClientHellos. */ + psSize_t tls13NumClientHelloKeyShares; + /* Supported signature algorithms. */ + uint16_t supportedSigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS]; + psSize_t supportedSigAlgsLen; + + psSizeL_t tls13PadLen; + psSizeL_t tls13BlockSize; + psBool_t tls13CiphersuitesEnabledClient; + psSize_t minDhBits; + + short ticketResumption; /* Client: 1 to use. Server N/A */ + short maxFragLen; /* Client: 512 etc.. Server: -1 to disable */ + short truncHmac; /* Client: 1 to use. Server: -1 to disable */ + short extendedMasterSecret; /* On by default. -1 to disable */ + short trustedCAindication; /* Client: 1 to use */ + short fallbackScsv; /* Client: 1 to use */ + int32 versionFlag; /* The SSL_FLAGS_TLS_ version (+ DTLS flag here) */ +} sslSessOpts_t; + +/** matrixSslLoadKeysOpts_t: options for matrixSslLoadKeys. */ +typedef struct { + uint32_t flags; /* LOAD_KEYS_OPT_* */ + int32_t key_type; + uint32_t privAsset; /* Used with RoT (#define USE_ROT_CRYPTO). */ + psCurve16_t privAssetCurveId; + psSize_t privAssetModulusNBytes; +} matrixSslLoadKeysOpts_t; +#define LOAD_KEYS_OPT_ALLOW_OUT_OF_DATE_CERT_PARSE (1 << 0) + +/** Structure for passing client-side key and cert selection requirements + to the sslIdentityCb_t type callback function. The structure is filled + with information from the server's CertificateRequest message. +*/ +typedef struct +{ + /* Number of End Entity certificate supplying certificate authorities + accepted by the peer. Both arrays caNames, and caNameLens have this + many elements. */ + psSize_t nCas; + + /* Array of certificate authority names, binary DER encoding, as received + from the peer. Each element caNames[N] is a binary string whose lenght + is caNameLens[N] octets. + + These names can be memcmp()'d with values available from the + certificate subject/issuer names. */ + const unsigned char **caNames; + psSize_t *caNameLens; + + /* Supported signature algorithm masks for transport and + certificate chains (latter for TLS1.3) */ + uint32_t peerSigAlgMask; + uint32_t peerCertSigAlgMask; + + /* Algorithms supported by peer for session signature. The values are one + of SignatureAndHashAlgorithm for TLS12, and one of SignatureScheme + values for TLS13 The selected identity key needs to be usable for + producing authentication signature with this identified algoritm + combination. */ + psSize_t peerSigAlgsLen; + uint16_t peerSigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS]; + + /* Algorithms supported by peer for certificate chains. If the session is + not TLS13 (or beyond), number of algorithms is always 0. */ + psSize_t peerCertSigAlgsLen; + uint16_t peerCertSigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS]; +} sslKeySelectInfo_t; + +/* Callback function of this type is called from the matrix library after it + has performed certificate path construction/validation for the certificate + presented by the peer (either the web server cert, or the client + certificate. This function can accept or reject the tls connection on its + discretion. + + Allowed return values: + * PS_SUCCCESS: + connection is OK - returning this will clear any pending from + potentially failed certificate validation. + * SSL_ALLOW_ANON_CONNECTION: + connection is accepted, but is later considered as anonymous + * >0 TLS alert to send to the peer (one of SSL_ALERT_ codes) + * <0 Internal error; sending SSL_ALERT_INTERNAL_ERROR to peer. */ +typedef int32_t (*sslCertCb_t)( + ssl_t *ssl, + psX509Cert_t *cert, + int32_t alert); + +/* Identity callback type. + + Callback function with signature of sslIdentityCb will be caled from the + matrix library to obtain key material for TLS client authentication. The + 'ssl' identifies the handshake to authenticate, and 'keySpec' identifies + the key (type, certificate issuer) accepted by the peer. + + If this callback is set, it will be exclusively used for arranging + keys used for client authentication, regardless if identities + (keys) were provided when calling matrixSslNewClientSession(). + + The callback shall use function matrixSslSetClientIdentity() to + select the keys. + + The callback must return 0 on success and < 0 on failure (when key + or cert could not be loaded). +*/ +typedef int32_t (*sslIdentityCb_t)( + ssl_t *ssl, + const sslKeySelectInfo_t *keySpec); + +/* TLS extension callback type. + + Callback function of this type is called from the matrix library to report + each received TLS Hello Extension for the application */ +typedef int32_t (*sslExtCb_t)( + ssl_t *ssl, + uint16_t extType, + uint8_t extLen, + void *e); + +/* sslPubkeyId_t structure is given as a key selector to pubkeyCB_t type + function used for selecting the identity key pair for the SSL server. */ +typedef struct +{ + unsigned short keyType; + unsigned short hashAlg; + unsigned short curveFlags; + unsigned short dhParamsRequired; + /* Name of the (virtual)server the peer connected to. The pubkeyCb should + return a certificate having this name as its subject name CN, or as a + subjectAltName. */ + char *serverName; +} sslPubkeyId_t; + +/* Public key callback type. + + The public key callback is called from the library on the + TLS server side to retrieve a keypair to use for server authentication for + the connection described by 'ssl' using algoritms specified by 'keyId'. + + This callback is not called, if the server side session was created using + matrixSslNewServerSession() and the server identity keys were already + provided during that call. + + This callback may be called multiple times with different 'keyId' (key + types in particular) for each 'ssl' connection. The callback is not called + for the same session after it has returned non-null value (found usable + keypair). + + The function shall return a sslKeys_t instance, or a NULL pointer in case + suitable keys are not found. */ +typedef sslKeys_t *(*pubkeyCb_t)( + ssl_t *ssl, + const sslPubkeyId_t *keyId); + +/* PSK callback type. + + The PSK callback is called from the library to retrieve + shared secret corresponding to the pskId from the application key + storage. The application returns returns PS_SUCCESS and fills in the key + into psk, and key length into pskLen if the key corresponding to the given + pskId is found. If key is not found, a negative error code shall be + returned resulting into aborted handshake. */ +typedef int32_t (*pskCb_t)( + ssl_t *ssl, + const unsigned char pskId[SSL_PSK_MAX_ID_SIZE], + uint8_t pskIdLen, + unsigned char *psk[SSL_PSK_MAX_KEY_SIZE], + uint8_t *pskLen); + +/* OCSP callback type. */ +typedef int32_t (*ocspCb_t)( + ssl_t *ssl, + psOcspResponse_t *response, + psX509Cert_t *cert, + int32_t status); + +/* SNI callback type. The SNI callback is called from the matrix library on the + server side to retrieve server Identity Keys corresponding to the virtual + hostname received from the TLS ServerNameIndication. The callback shall + fill into newKeys the key material to use. The provided key material, if + any, shall be allocated using matrixSslNewKeys(), and the matrix library + will take care of freeing the keys when they are no longer needed. + + Note, that if both sniCb and pubkeyCb have been set, and sniCb provides key + material, the pubkeyCb will not be called. */ +typedef void (*sniCb_t)( + void *ssl, + char *hostname, + int32 hostnameLen, + sslKeys_t **newKeys); + +/** Security operation IDs. */ +typedef enum +{ + secop_undefined = 0, + secop_symmetric_encrypt, + secop_hmac, + secop_hash_for_sig, + secop_rsa_encrypt, + secop_rsa_decrypt, + secop_rsa_sign, + secop_rsa_verify, + secop_rsa_load_key, + secop_ecdsa_sign, + secop_ecdsa_verify, + secop_ecdsa_load_key, + secop_dh_import_pub, + secop_ecdh_import_pub, + secop_proto_version_check, + secop_sigalg_check, + secop_cipher_check +} psSecOperation_t; + +/** Security callback. + This function will be called by MatrixSSL or Matrix Crypto to query + the permissibility of an operation. */ +typedef psRes_t (*securityCb_t)( + void *ctx, /* Pointer to either ssl_t or crypto_t */ + psSecOperation_t op, /* Crypto/TLS op, e.g. CRYPTO_OP_RSA_PKCS1_5_SIGN. */ + psSizeL_t nbits, /* Bits to use in the operation (key size or similar.) */ + void *extraData); /* Extra decision-making info; format depends on op. */ + +/** Pre-defined security profiles. */ +typedef enum +{ + secprofile_default = 0, + secprofile_wpa3_1_0_enterprise_192 = 1 +} psPreDefinedSecProfile_t; + +#endif diff --git a/matrixssl/matrixsslApiVer.h b/matrixssl/matrixsslApiVer.h new file mode 100644 index 0000000..f333055 --- /dev/null +++ b/matrixssl/matrixsslApiVer.h @@ -0,0 +1,252 @@ +/** + * @file matrixsslApiVer.h + * @version $Format:%h%d$ + * + * Public header file for MatrixSSL. + * This sub-header of matrixsslApi.h contains protocol version related + * defines. + */ +/* + * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +/******************************************************************************/ + +#ifndef _h_MATRIXSSL_API_VER +# define _h_MATRIXSSL_API_VER + +/** + - USE_TLS versions must 'stack' for compiling purposes + - must enable TLS if enabling TLS 1.1 + - must enable TLS 1.1 if enabling TLS 1.2 + - Use the DISABLE_TLS_ defines to disallow specific protocols at runtime + that have been enabled via USE_TLS_. + - There is no DISABLE_TLS_ for the latest version of the protocol. If + you don't want to use that version disable the USE_TLS_ define instead + The USE_TLS_1_x_AND_ABOVE simplifies this configuration. + @security To enable SSL3.0, see below. + */ +# define USE_TLS /**< DO NOT DISABLE @security NIST_MAY */ +# define USE_TLS_1_1 /**< DO NOT DISABLE @security NIST_SHALL */ +# define USE_TLS_1_2 /**< DO NOT DISABLE @security NIST_SHOULD */ +# define DISABLE_SSLV3 /**< DO NOT DISABLE, undef below if required + @security NIST_SHALL_NOT */ + +/* This looks a bit clumsy, because TLS 1.3 code still requires a separate + define (USE_TLS_1_3) to enable. */ +# if defined USE_TLS_1_2_AND_ABOVE +# ifndef DISABLE_TLS_1_3 +# define USE_TLS_1_3 +# endif +# define USE_TLS_1_2 +# define DISABLE_TLS_1_1 +# define DISABLE_TLS_1_0 +# elif defined USE_TLS_1_1_AND_ABOVE +# ifndef DISABLE_TLS_1_3 +# define USE_TLS_1_3 +# endif +# define USE_TLS_1_2 +# define DISABLE_TLS_1_0 +# elif defined USE_TLS_1_0_AND_ABOVE +# ifndef DISABLE_TLS_1_3 +# define USE_TLS_1_3 +# endif +# define USE_TLS_1_2 +# define USE_TLS_1_1 +/** @security undef DISABLE_SSLV3 here if required */ +# else +# error Must define USE_TLS_1_x_AND_ABOVE +# endif + +/* Type used for storing protocol versions. */ +typedef uint32_t psProtocolVersion_t; + +/* Official on-the-wire version identifiers. */ +enum PACKED +{ + v_undefined_enc = 0, + v_ssl_3_0_enc = 0x0300, + v_tls_1_0_enc = 0x0301, + v_tls_1_1_enc = 0x0302, + v_tls_1_2_enc = 0x0303, + v_tls_1_3_enc = 0x0304, + v_tls_1_3_draft_22_enc = 0x7f16, + v_tls_1_3_draft_23_enc = 0x7f17, + v_tls_1_3_draft_24_enc = 0x7f18, + v_tls_1_3_draft_26_enc = 0x7f1a, + v_tls_1_3_draft_28_enc = 0x7f1c, + v_dtls_1_0_enc = 0xfeff, + v_dtls_1_2_enc = 0xfefd +}; + +/** A version v can be either: + 1. Supported by the compile-time config + --> if (v & v_compiled_in) + 2. Supported for the current connection + --> if (SUPP_VER(ssl, v)) + 3. The active version + --> if (ACTV_VER(ssl, v)) + 4. The negotiated version + --> if (NGTD_VER(ssl, v)) + + An activated version is the version we are currently following. + This affects e.g. the format of our ClientHello, whether or not + to allow sending early data, and whether to expect the peer's + hello message to have TLS or DTLS style record headers. + + An active version becomes negotiated when we have sufficient + information from the peer to know that it also supports the + version. +*/ + +/** Bits 0 to 23 are reserved for versions. */ +#define VER_MAX_BIT 23 + +/** Bits 24 to 31 are reserved for version attributes. */ +#define VER_ATTRIB_MAX_BIT 31 + +/* MatrixSSL's internal protocol version identifiers. */ +enum PACKED +{ + v_undefined = 0, + + /** Versions. The ordering of the numeric values of the enumerators + MUST correspond to the chronological order in which the + protocol specifications were published, for example: + v_tls_1_1 < v_tls_1_2. This affects e.g. the default + priority order. */ + v_ssl_3_0 = 1ULL << 0, + v_tls_1_0 = 1ULL << 1, + v_tls_1_1 = 1ULL << 2, + v_dtls_1_0 = 1ULL << 3, + v_tls_1_2 = 1ULL << 4, + v_dtls_1_2 = 1ULL << 5, + v_tls_1_3_draft_22 = 1ULL << 6, + v_tls_1_3_draft_23 = 1ULL << 7, + v_tls_1_3_draft_24 = 1ULL << 8, + v_tls_1_3_draft_26 = 1ULL << 9, + v_tls_1_3_draft_28 = 1ULL << 10, + v_tls_1_3 = 1ULL << 11, + + /** Version attributes. */ + v_tls_negotiated = 1ULL << 24, /* Version negotiation complete? */ + + /** Version combinations. */ + + /** Any supported TLS 1.3 draft version. */ + v_tls_1_3_draft_any = (v_tls_1_3_draft_22 + | v_tls_1_3_draft_23 + | v_tls_1_3_draft_24 + | v_tls_1_3_draft_26 + | v_tls_1_3_draft_28), + /** Any supported TLS 1.3 version. */ + v_tls_1_3_any = (v_tls_1_3 + | v_tls_1_3_draft_any), + /** Any supported TLS version. */ + v_tls_any = (v_tls_1_0 | v_tls_1_1 | v_tls_1_2 | v_tls_1_3_any), + /** Any DTLS version. */ + v_dtls_any = (v_dtls_1_0 | v_dtls_1_2), + /** Any supported legacy version (TLS <1.3) */ + v_tls_legacy = (v_tls_1_0 | v_tls_1_1 | v_tls_1_2 | v_dtls_any), + /** Any supported TLS 1.3 version that uses AAD in record encryption. */ + v_tls_1_3_aad = (v_tls_1_3 + | v_tls_1_3_draft_26 + | v_tls_1_3_draft_28), + /** Any supported TLS 1.3 version that uses 51 as key_share ID */ + v_tls_1_3_key_share_51 = (v_tls_1_3 + | v_tls_1_3_draft_23 + | v_tls_1_3_draft_24 + | v_tls_1_3_draft_26 + | v_tls_1_3_draft_28), + /** Any supported version that uses an explicit IV in CBC mode. */ + v_tls_explicit_iv = (v_dtls_1_0 | v_dtls_1_2 | v_tls_1_1 | v_tls_1_2), + /** Any recommended TLS version. TODO: remove draft #28 once the + RFC version becomes widely supported enough. */ + v_tls_recommended = (v_tls_1_2 | v_tls_1_3 | v_tls_1_3_draft_28), + /** Any recommended DTLS version. */ + v_dtls_recommended = v_dtls_1_2, + /** Any version that allows SHA-2 based ciphersuites. */ + v_tls_sha2 = (v_tls_1_2 | v_tls_1_3_any | v_dtls_1_2), + /** Any version that does NOT allow SHA-2 based ciphersuites. */ + v_tls_no_sha2 = (v_ssl_3_0 | v_tls_1_0 | v_tls_1_1 | v_dtls_1_0), + /** Any version that may need the BEAST workaround. */ + v_tls_need_beast_workaround = (v_ssl_3_0 | v_tls_1_0), + /** Any version that uses the unsupported_extension alert. */ + v_tls_with_unsupported_extension_alert = (v_tls_1_2 + | v_dtls_1_2 + | v_tls_1_3_any), + /** Any version that uses HMAC instead of a custom MAC construction. */ + v_tls_with_hmac = (v_tls_any | v_dtls_any), + /** Any version that supports the signature_algorithms extension. */ + v_tls_with_signature_algorithms = (v_tls_1_2 + | v_tls_1_3_any + | v_dtls_1_2), + /** Any version that supports PKCS #1.5 sigs in CV and SKE. */ + v_tls_with_pkcs15_auth = (v_tls_1_2 | v_dtls_1_2), + /** Any version that uses the TLS 1.2 PRF. */ + v_tls_with_tls_1_2_prf = (v_tls_1_2 | v_dtls_1_2), + /** Any version supported by build-time-config. */ + v_compiled_in = (0 +# if !defined(DISABLE_SSLV3) + | v_ssl_3_0 +# endif +# if defined(USE_TLS) && !defined(DISABLE_TLS_1_0) + | v_tls_1_0 +# endif +# if defined(USE_TLS_1_1) && !defined(DISABLE_TLS_1_1) + | v_tls_1_1 +# if defined(USE_DTLS) + | v_dtls_1_0 +# endif +# endif +# if defined(USE_TLS_1_2) && !defined(DISABLE_TLS_1_2) + | v_tls_1_2 +# if defined(USE_DTLS) + | v_dtls_1_2 +# endif +# endif +# if defined(USE_TLS_1_3) && !defined(DISABLE_TLS_1_3) + | v_tls_1_3_any +# endif + ) +}; + +/* Version flags. These are deprecated; psProtocolVersion_t and the + related APIs should be used instead. */ +# define SSL_FLAGS_SSLV3 (1U << 10) +# define SSL_FLAGS_TLS (1U << 11) +# define SSL_FLAGS_TLS_1_0 SSL_FLAGS_TLS /* For naming consistency */ +# define SSL_FLAGS_TLS_1_1 (1U << 12) +# define SSL_FLAGS_TLS_1_2 (1U << 13) +# define SSL_FLAGS_DTLS (1U << 14) +# define SSL_FLAGS_TLS_1_3 (1U << 15) +# define SSL_FLAGS_TLS_1_3_DRAFT_22 (1U << 26) +# define SSL_FLAGS_TLS_1_3_DRAFT_23 (1U << 27) +# define SSL_FLAGS_TLS_1_3_DRAFT_24 (1U << 28) +# define SSL_FLAGS_TLS_1_3_DRAFT_26 (1U << 29) +# define SSL_FLAGS_TLS_1_3_DRAFT_28 (1U << 30) +# define SSL_FLAGS_TLS_1_3_NEGOTIATED (1U << 31) + +#endif diff --git a/matrixssl/matrixsslInitVer.c b/matrixssl/matrixsslInitVer.c index a19bb4d..cdad56c 100644 --- a/matrixssl/matrixsslInitVer.c +++ b/matrixssl/matrixsslInitVer.c @@ -48,6 +48,13 @@ psBool_t matrixSslTlsVersionRangeSupported(psProtocolVersion_t low, return PS_FALSE; } + if (!(low & v_tls_any) || !(high & v_tls_any)) + { + psTraceInfo("matrixSslTlsVersionRangeSupported: only TLS " + "versions supported by this API\n"); + return PS_FALSE; + } + if (!COMPILED_IN_VER(low) || !COMPILED_IN_VER(high)) { return PS_FALSE; @@ -56,7 +63,7 @@ psBool_t matrixSslTlsVersionRangeSupported(psProtocolVersion_t low, low <<= 1; while (low < high) { - if (!COMPILED_IN_VER(low)) + if ((low & v_tls_any) && !COMPILED_IN_VER(low)) { return PS_FALSE; } @@ -84,12 +91,11 @@ matrixSslSessOptsSetClientTlsVersionRange(sslSessOpts_t *options, i = 0; do { - if (COMPILED_IN_VER(high)) + if ((high & v_tls_any) && COMPILED_IN_VER(high)) { - versions[i] = high; + versions[i++] = high; + numVersions++; } - numVersions++; - i++; high >>= 1; } while (high >= low); @@ -105,9 +111,6 @@ matrixSslSessOptsSetClientTlsVersions(sslSessOpts_t *options, { uint8_t i, k; psProtocolVersion_t highestVersion = 0; -# ifdef USE_TLS_1_3 - psBool_t haveTls13Draft28 = PS_FALSE; -# endif if (options == NULL) { @@ -124,15 +127,6 @@ matrixSslSessOptsSetClientTlsVersions(sslSessOpts_t *options, "TLS_MAX_SUPPORTED_VERSIONS.\n"); return PS_ARG_FAIL; } -# ifdef USE_TLS_1_3 - for (i = 0; i < versionsLen; i++) - { - if (versions[i] == v_tls_1_3_draft_28) - { - haveTls13Draft28 = PS_TRUE; - } - } -# endif options->supportedVersionsLen = 0; for (i = 0, k = 0; i < versionsLen; i++) @@ -141,6 +135,8 @@ matrixSslSessOptsSetClientTlsVersions(sslSessOpts_t *options, { psTraceErrr("Unsupported version. Please enable more " \ "versions in matrixsslConfig.h.\n"); + psTraceStrInfo("Unsupported version: %s\n", + VER_TO_STR(versions[i])); return PS_ARG_FAIL; } options->supportedVersions[k++] = versions[i]; @@ -149,15 +145,6 @@ matrixSslSessOptsSetClientTlsVersions(sslSessOpts_t *options, { highestVersion = versions[i]; } -# ifdef USE_TLS_1_3 - if (versions[i] == v_tls_1_3 && !haveTls13Draft28) - { - /* Very little support in the wild for TLS 1.3 RFC version, - so add draft #28 as well. TODO: remove.*/ - options->supportedVersions[k++] = v_tls_1_3_draft_28; - options->supportedVersionsLen++; - } -# endif } /* Set the versionFlag always to highest version. Note that @@ -192,12 +179,11 @@ matrixSslSessOptsSetServerTlsVersionRange(sslSessOpts_t *options, i = 0; do { - if (COMPILED_IN_VER(high)) + if ((high & v_tls_any) && COMPILED_IN_VER(high)) { - versions[i] = high; + versions[i++] = high; + numVersions++; } - numVersions++; - i++; high >>= 1; } while (high >= low); @@ -212,9 +198,6 @@ matrixSslSessOptsSetServerTlsVersions(sslSessOpts_t *options, int32_t versionsLen) { uint8_t i, k; -# ifdef USE_TLS_1_3 - psBool_t haveTls13Draft28 = PS_FALSE; -# endif /* On the server side the version handling goes either of two @@ -240,15 +223,6 @@ matrixSslSessOptsSetServerTlsVersions(sslSessOpts_t *options, return PS_ARG_FAIL; } -# ifdef USE_TLS_1_3 - for (i = 0; i < versionsLen; i++) - { - if (versions[i] == v_tls_1_3_draft_28) - { - haveTls13Draft28 = PS_TRUE; - } - } -# endif for (i = 0, k = 0; i < versionsLen; i++) { if (!matrixSslTlsVersionRangeSupported(versions[i], versions[i])) @@ -263,15 +237,6 @@ matrixSslSessOptsSetServerTlsVersions(sslSessOpts_t *options, } options->supportedVersions[k++] = versions[i]; options->supportedVersionsLen++; -# ifdef USE_TLS_1_3 - if (versions[i] == v_tls_1_3 && !haveTls13Draft28) - { - /* Very little support in the wild for TLS 1.3 RFC version, - so add draft #28 as well. TODO: remove.*/ - options->supportedVersions[k++] = v_tls_1_3_draft_28; - options->supportedVersionsLen++; - } -# endif } if (versionsLen == 1) @@ -313,7 +278,7 @@ void addVersion(ssl_t *ssl, psProtocolVersion_t ver) causing handshake failure. */ if ((ver & v_tls_1_3_any) - && IS_CLIENT(ssl) + && MATRIX_IS_CLIENT(ssl) && !ssl->tls13CiphersuitesEnabledClient) { psTraceInfo("Warning: tried to enable TLS 1.3 without enabling " \ @@ -361,63 +326,63 @@ int32 initSupportedVersions(ssl_t *ssl, sslSessOpts_t *options) flags = options->versionFlag; if (flags & SSL_FLAGS_DTLS) { - addVersion(ssl, v_dtls_1_0); highestSupported = v_dtls_1_0; if (flags & SSL_FLAGS_TLS_1_2) { addVersion(ssl, v_dtls_1_2); highestSupported = v_dtls_1_2; } + addVersion(ssl, v_dtls_1_0); } else { - if ((flags & SSL_FLAGS_TLS_1_0) - && !SUPP_VER(ssl, v_tls_1_0)) - { - addVersion(ssl, v_tls_1_0); - } - if ((flags & SSL_FLAGS_TLS_1_1) - && !SUPP_VER(ssl, v_tls_1_1)) - { - addVersion(ssl, v_tls_1_1); - } - if ((flags & SSL_FLAGS_TLS_1_2) - && !SUPP_VER(ssl, v_tls_1_2)) - { - addVersion(ssl, v_tls_1_2); - } #ifdef USE_TLS_1_3 if ((flags & SSL_FLAGS_TLS_1_3) && !SUPP_VER(ssl, v_tls_1_3)) { addVersion(ssl, v_tls_1_3); } - if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_22) - && !SUPP_VER(ssl, v_tls_1_3_draft_22)) + if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_28) && + !SUPP_VER(ssl, v_tls_1_3_draft_28)) { - addVersion(ssl, v_tls_1_3_draft_22); - } - if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_23) && - !SUPP_VER(ssl, v_tls_1_3_draft_23)) - { - addVersion(ssl, v_tls_1_3_draft_23); - } - if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_24) && - !SUPP_VER(ssl, v_tls_1_3_draft_24)) - { - addVersion(ssl, v_tls_1_3_draft_24); + addVersion(ssl, v_tls_1_3_draft_28); } if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_26) && !SUPP_VER(ssl, v_tls_1_3_draft_26)) { addVersion(ssl, v_tls_1_3_draft_26); } - if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_28) && - !SUPP_VER(ssl, v_tls_1_3_draft_28)) + if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_24) && + !SUPP_VER(ssl, v_tls_1_3_draft_24)) { - addVersion(ssl, v_tls_1_3_draft_28); + addVersion(ssl, v_tls_1_3_draft_24); + } + if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_23) && + !SUPP_VER(ssl, v_tls_1_3_draft_23)) + { + addVersion(ssl, v_tls_1_3_draft_23); + } + if ((flags & SSL_FLAGS_TLS_1_3_DRAFT_22) + && !SUPP_VER(ssl, v_tls_1_3_draft_22)) + { + addVersion(ssl, v_tls_1_3_draft_22); } #endif + if ((flags & SSL_FLAGS_TLS_1_2) + && !SUPP_VER(ssl, v_tls_1_2)) + { + addVersion(ssl, v_tls_1_2); + } + if ((flags & SSL_FLAGS_TLS_1_1) + && !SUPP_VER(ssl, v_tls_1_1)) + { + addVersion(ssl, v_tls_1_1); + } + if ((flags & SSL_FLAGS_TLS_1_0) + && !SUPP_VER(ssl, v_tls_1_0)) + { + addVersion(ssl, v_tls_1_0); + } } } @@ -446,7 +411,7 @@ int32 initSupportedVersions(ssl_t *ssl, sslSessOpts_t *options) - If client, we shall encode the first ClientHello according in the TLS 1.3 ClientHello format. */ - if (IS_CLIENT(ssl)) + if (MATRIX_IS_CLIENT(ssl)) { if (highestSupported == v_undefined) { diff --git a/matrixssl/matrixsslKeys.c b/matrixssl/matrixsslKeys.c index 1e64374..d5327f0 100644 --- a/matrixssl/matrixsslKeys.c +++ b/matrixssl/matrixsslKeys.c @@ -44,6 +44,10 @@ #if defined(USE_CA_CERTIFICATES) || defined(USE_IDENTITY_CERTIFICATES) +# ifdef USE_ROT_CRYPTO +# include "../crypto-rot/rotCommon.h" +# endif + # ifdef USE_CERT_PARSE static psRes_t handleAuthFailDate(matrixSslLoadKeysOpts_t *opts) @@ -314,11 +318,16 @@ matrixSslAddIdentity(sslKeys_t *keys, sslIdentity_t *identity) { # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH) sslIdentity_t **p; + /* Push the new key at the end of the list, so that routines using the keys can easily prefer the first one added. */ for (p = &(keys->identity); *p; p = &((*p)->next)) ; *p = identity; + + psTraceInfo("Adding identity with key type: "); + psTracePrintPubKeyTypeAndSize(NULL, &identity->privKey); + return identity; # else return NULL; @@ -502,6 +511,74 @@ static psRes_t sslLoadCert(psPool_t *pool, return rc; } +psRes_t psRotSetupIdentityKey(matrixSslLoadKeysOpts_t *opts, + psPubKey_t *idKey) +{ +# ifdef USE_ROT_CRYPTO + int32_t err; +# ifdef USE_ROT_ECC + const psEccCurve_t *curve; +# endif + + switch (opts->key_type) + { +# ifdef USE_ROT_ECC + case PS_ECC: + idKey->type = PS_ECC; + idKey->key.ecc.rotKeyType = ps_ecc_key_type_ecdsa; + + idKey->key.ecc.privAsset = opts->privAsset; + psTraceIntInfo("Using ECDSA private key asset: %u\n", + idKey->key.ecc.privAsset); + err = getEccParamById(opts->privAssetCurveId, + &curve); + psTraceStrInfo(" (%s curve)\n", curve->name); + idKey->key.ecc.curve = curve; + if (err < 0) + { + psTraceErrr("getEccParamById failed\n"); + return err; + } + idKey->keysize = curve->size * 2; + err = psRotLoadCurve(curve->curveId, + &idKey->key.ecc.domainAsset); + if (err < 0) + { + psTraceErrr("psRotLoadCurve failed\n"); + return err; + } + /* Do not take ownership of this asset - we are not responsible + for freeing. */ + idKey->key.ecc.longTermPrivAsset = PS_TRUE; + break; +# endif +# ifdef USE_ROT_RSA + case PS_RSA: + idKey->type = PS_RSA; + idKey->key.rsa.privSigAsset = opts->privAsset; + psTraceIntInfo("Using RSA private key asset: %u\n", + idKey->key.rsa.privSigAsset); + idKey->keysize = opts->privAssetModulusNBytes; + idKey->key.rsa.size = opts->privAssetModulusNBytes; + /* Do not take ownership of this asset - we are not responsible + for freeing. */ + idKey->key.rsa.longTermPrivAsset = PS_TRUE; + break; +# endif + default: + psTraceErrr("Unknown key type in psRotSetupIdentityKey\n"); + return PS_UNSUPPORTED_FAIL; + } + return PS_SUCCESS; + +# else + (void)opts; + (void)idKey; + psTraceErrr("USE_ROT_CRYPTO needed for psRotSetupIdentityKey\n"); + return PS_UNSUPPORTED_FAIL; +# endif /* USE_ROT_CRYPTO */ +} + psRes_t matrixSslCreateIdentityFromData(sslKeys_t *keys, const unsigned char *cert, @@ -516,22 +593,39 @@ matrixSslCreateIdentityFromData(sslKeys_t *keys, psX509Cert_t *idcert = NULL; int32 err; sslIdentity_t *id; + psRes_t rc; + + memset(&idkey, 0, sizeof(idkey)); err = sslLoadCert(keys->pool, &idcert, cert, cert_len, opts); if (err < PS_SUCCESS) { return err; } - err = sslLoadKeyPair(keys->pool, - &idkey, - keytype, - keypass, - keydata, - keydata_len); - if (err < PS_SUCCESS) + + if (opts && opts->privAsset != 0) { - psX509FreeCert(idcert); - return err; + rc = psRotSetupIdentityKey(opts, &idkey); + if (rc < 0) + { + psTraceErrr("psRotLoadIdentity failed\n"); + psX509FreeCert(idcert); + return rc; + } + } + else + { + err = sslLoadKeyPair(keys->pool, + &idkey, + keytype, + keypass, + keydata, + keydata_len); + if (err < PS_SUCCESS) + { + psX509FreeCert(idcert); + return err; + } } id = matrixSslCreateIdentity(keys, idkey, idcert); @@ -560,27 +654,48 @@ static psRes_t matrixSslLoadKeyMaterialMem(sslKeys_t *keys, { return PS_ARG_FAIL; } + +# ifdef USE_ROT_CRYPTO + if (privKeyType != PS_ECC && privKeyType != PS_RSA) + { + psTraceErrr("Only ECDSA/RSA auth keys supported by crypto-rot\n"); + return PS_ARG_FAIL; + } + if (opts && opts->privAsset != VAL_ASSETID_INVALID) + { + /* The asset ID overrides the plaintext key. */ + privBuf = NULL; + privLen = 0; + } +# endif /* USE_ROT_CRYPTO */ + err = matrixSslAddTrustAnchors(keys, NULL, CAbuf, CAlen, opts); if (err < PS_SUCCESS) { return err; } - err = matrixSslCreateIdentityFromData(keys, - certBuf, - certLen, - privKeyType, - NULL, - privBuf, - privLen, - opts); - if (err < PS_SUCCESS) + + if ((privBuf != NULL && certBuf != NULL) || + (opts != NULL && opts->privAsset != 0)) { + err = matrixSslCreateIdentityFromData(keys, + certBuf, + certLen, + privKeyType, + NULL, + privBuf, + privLen, + opts); + if (err < PS_SUCCESS) + { # if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH) - psX509FreeCert(keys->CAcerts); - keys->CAcerts = NULL; + psX509FreeCert(keys->CAcerts); + keys->CAcerts = NULL; # endif - return PS_CERT_AUTH_FAIL; + return PS_CERT_AUTH_FAIL; + } } + return PS_SUCCESS; } @@ -594,7 +709,7 @@ int32_t matrixSslLoadKeysMem(sslKeys_t *keys, matrixSslLoadKeysOpts_t *opts) { int32_t keytype = 0; - int32_t rc; + int32_t rc = PS_FAILURE; if (opts) { @@ -606,9 +721,11 @@ int32_t matrixSslLoadKeysMem(sslKeys_t *keys, keytype = 1; } + /* Note: previous versions used the constants 1 for RSA, + 2 for ECC and 3 for EDDSA. */ switch (keytype) { - case 1: /* RSA */ + case PS_RSA: rc = matrixSslLoadKeyMaterialMem(keys, certBuf, certLen, @@ -619,7 +736,7 @@ int32_t matrixSslLoadKeysMem(sslKeys_t *keys, PS_RSA, opts); break; - case 2: /* ECC */ + case PS_ECC: rc = matrixSslLoadKeyMaterialMem(keys, certBuf, certLen, @@ -630,7 +747,7 @@ int32_t matrixSslLoadKeysMem(sslKeys_t *keys, PS_ECC, opts); break; - case 3: /* ECDSA*/ + case PS_ED25519: rc = matrixSslLoadKeyMaterialMem(keys, certBuf, certLen, @@ -671,7 +788,6 @@ int32_t matrixSslLoadKeysMem(sslKeys_t *keys, return rc; } - #ifdef USE_RSA int32 matrixSslLoadRsaKeysMemExt(sslKeys_t *keys, const unsigned char *certBuf, @@ -769,7 +885,7 @@ int32 matrixSslLoadPkcs12Mem(sslKeys_t *keys, psPool_t *pool; int32 rc; psX509Cert_t *cert; - psPubKey_t idkey = {0}; + psPubKey_t idkey; sslIdentity_t *id; if (keys == NULL) @@ -779,6 +895,8 @@ int32 matrixSslLoadPkcs12Mem(sslKeys_t *keys, pool = keys->pool; PS_POOL_USED(pool); + Memset(&idkey, 0, sizeof(idkey)); + if (macPass == NULL) { mPass = (unsigned char *) importPass; @@ -940,7 +1058,11 @@ int32 psTestUserEc(int32 ecFlags, const sslKeys_t *keys) if (cert->publicKey.type == PS_ECC) { eccKey = &cert->publicKey.key.ecc; - res = psTestUserEcID(eccKey->curve->curveId, ecFlags); + res = PS_FAILURE; + if (eccKey->curve) + { + res = psTestUserEcID(eccKey->curve->curveId, ecFlags); + } if (res == PS_SUCCESS) { goodEccCount++; @@ -951,6 +1073,101 @@ int32 psTestUserEc(int32 ecFlags, const sslKeys_t *keys) # endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */ return goodEccCount > 0 || otherKeyCount > 0; } + +/** + Generate and cache an ephemeral ECC key for later use in ECDHE key exchange. + @param[out] keys Keys structure to hold ephemeral keys + @param[in] curve ECC curve to generate key on, or NULL to generate for all + supported curves. + @param[in] hwCtx Context for hardware crypto. + */ +int32_t matrixSslGenEphemeralEcKey(sslKeys_t *keys, + psEccKey_t *ecc, + const psEccCurve_t *curve, + void *hwCtx) +{ +# if ECC_EPHEMERAL_CACHE_USAGE > 0 + psTime_t t; +# endif + int32_t rc = PS_FAILURE; + + if (keys == NULL || curve == NULL) + { + return PS_ARG_FAIL; + } + +# if ECC_EPHEMERAL_CACHE_USAGE > 0 + psGetTime(&t, keys->poolUserPtr); + psLockMutex(&keys->cache.lock); + if (keys->cache.eccPrivKey.curve != curve) + { + psTraceStrInfo("Generating ephemeral %s key (new curve)\n", + curve->name); + goto L_REGEN; + } + if (keys->cache.eccPrivKeyUse > ECC_EPHEMERAL_CACHE_USAGE) + { + psTraceStrInfo("Generating ephemeral %s key (usage exceeded)\n", + curve->name); + goto L_REGEN; + } + if (psDiffMsecs(keys->cache.eccPrivKeyTime, t, keys->poolUserPtr) > + (1000 * ECC_EPHEMERAL_CACHE_SECONDS)) + { + psTraceStrInfo("Generating ephemeral %s key (time exceeded)\n", + curve->name); + goto L_REGEN; + } + keys->cache.eccPrivKeyUse++; + rc = PS_SUCCESS; + if (ecc) + { + rc = psEccCopyKey(ecc, &keys->cache.eccPrivKey); + } + psUnlockMutex(&keys->cache.lock); + return rc; + +L_REGEN: + if (keys->cache.eccPrivKeyUse) + { + /* We use eccPrivKeyUse == 0 as a flag to note the key not allocated */ + psEccClearKey(&keys->cache.eccPrivKey); + keys->cache.eccPrivKeyUse = 0; + } +# ifdef USE_ROT_ECC + keys->cache.eccPrivKey.rotKeyType = ps_ecc_key_type_ecdhe; +# endif + rc = psEccGenKey(keys->pool, &keys->cache.eccPrivKey, curve, hwCtx); + if (rc < 0) + { + psUnlockMutex(&keys->cache.lock); + return rc; + } + keys->cache.eccPrivKeyTime = t; + keys->cache.eccPrivKeyUse = 1; + rc = PS_SUCCESS; + if (ecc) + { + rc = psEccCopyKey(ecc, &keys->cache.eccPrivKey); + } + psUnlockMutex(&keys->cache.lock); + return rc; +# else + /* Not using ephemeral caching. */ + if (ecc) + { +# ifdef USE_ROT_ECC + ecc->rotKeyType = ps_ecc_key_type_ecdhe; +# endif + psTraceStrInfo("Generating ephemeral %s key (new curve)\n", + curve->name); + rc = psEccGenKey(keys->pool, ecc, curve, hwCtx); + return rc; + } + rc = PS_SUCCESS; + return rc; +# endif /* ECC_EPHEMERAL_CACHE_USAGE > 0 */ +} #endif /* USE_ECC */ #ifdef MATRIX_USE_FILE_SYSTEM @@ -971,7 +1188,7 @@ int32 matrixSslLoadPkcs12(sslKeys_t *keys, psPool_t *pool; int32 rc; psX509Cert_t *cert; - psPubKey_t idkey = {0}; + psPubKey_t idkey; sslIdentity_t *id; if (keys == NULL) @@ -981,6 +1198,8 @@ int32 matrixSslLoadPkcs12(sslKeys_t *keys, pool = keys->pool; PS_POOL_USED(pool); + Memset(&idkey, 0, sizeof(idkey)); + if (macPass == NULL) { mPass = (unsigned char *) importPass; @@ -1069,10 +1288,10 @@ static psRes_t matrixSslLoadKeyMaterial(sslKeys_t *keys, psFree(idkey, pool); } } -# endif +# endif /* USE_IDENTITY_CERTIFICATES */ return err; } -#endif +#endif /* USE_RSA || USE_ECC */ # ifdef USE_RSA /******************************************************************************/ @@ -1106,8 +1325,6 @@ int32 matrixSslLoadRsaKeys(sslKeys_t *keys, PS_RSA, NULL); } - -/******************************************************************************/ # endif /* USE_RSA */ # ifdef USE_ECC @@ -1142,93 +1359,6 @@ int32 matrixSslLoadEcKeys(sslKeys_t *keys, PS_ECC, NULL); } - -/** - Generate and cache an ephemeral ECC key for later use in ECDHE key exchange. - @param[out] keys Keys structure to hold ephemeral keys - @param[in] curve ECC curve to generate key on, or NULL to generate for all - supported curves. - @param[in] hwCtx Context for hardware crypto. - */ -int32_t matrixSslGenEphemeralEcKey(sslKeys_t *keys, - psEccKey_t *ecc, - const psEccCurve_t *curve, - void *hwCtx) -{ -# if ECC_EPHEMERAL_CACHE_USAGE > 0 - psTime_t t; -# endif - int32_t rc; - - if (keys == NULL || curve == NULL) - { - return PS_ARG_FAIL; - } - -# if ECC_EPHEMERAL_CACHE_USAGE > 0 - psGetTime(&t, keys->poolUserPtr); - psLockMutex(&keys->cache.lock); - if (keys->cache.eccPrivKey.curve != curve) - { - psTraceStrInfo("Generating ephemeral %s key (new curve)\n", - curve->name); - goto L_REGEN; - } - if (keys->cache.eccPrivKeyUse > ECC_EPHEMERAL_CACHE_USAGE) - { - psTraceStrInfo("Generating ephemeral %s key (usage exceeded)\n", - curve->name); - goto L_REGEN; - } - if (psDiffMsecs(keys->cache.eccPrivKeyTime, t, keys->poolUserPtr) > - (1000 * ECC_EPHEMERAL_CACHE_SECONDS)) - { - psTraceStrInfo("Generating ephemeral %s key (time exceeded)\n", - curve->name); - goto L_REGEN; - } - keys->cache.eccPrivKeyUse++; - rc = PS_SUCCESS; - if (ecc) - { - rc = psEccCopyKey(ecc, &keys->cache.eccPrivKey); - } - psUnlockMutex(&keys->cache.lock); - return rc; - -L_REGEN: - if (keys->cache.eccPrivKeyUse) - { - /* We use eccPrivKeyUse == 0 as a flag to note the key not allocated */ - psEccClearKey(&keys->cache.eccPrivKey); - keys->cache.eccPrivKeyUse = 0; - } - rc = psEccGenKey(keys->pool, &keys->cache.eccPrivKey, curve, hwCtx); - if (rc < 0) - { - psUnlockMutex(&keys->cache.lock); - return rc; - } - keys->cache.eccPrivKeyTime = t; - keys->cache.eccPrivKeyUse = 1; - rc = PS_SUCCESS; - if (ecc) - { - rc = psEccCopyKey(ecc, &keys->cache.eccPrivKey); - } - psUnlockMutex(&keys->cache.lock); - return rc; -# else - /* Not using ephemeral caching. */ - if (ecc) - { - rc = psEccGenKey(keys->pool, ecc, curve, hwCtx); - return rc; - } - rc = PS_SUCCESS; - return rc; -# endif /* ECC_EPHEMERAL_CACHE_USAGE > 0 */ -} # endif /* USE_ECC */ # if defined(USE_IDENTITY_CERTIFICATES) @@ -1240,7 +1370,7 @@ psRes_t matrixSslLoadKeys(sslKeys_t *keys, matrixSslLoadKeysOpts_t *opts) { int32_t keytype = 0; - int32_t rc; + int32_t rc = PS_FAILURE; if (opts) { @@ -1311,6 +1441,7 @@ psRes_t matrixSslLoadKeys(sslKeys_t *keys, return rc; } # endif + # ifdef REQUIRE_DH_PARAMS /******************************************************************************/ /* diff --git a/matrixssl/matrixsslNet.h b/matrixssl/matrixsslNet.h index 581325b..1d090ad 100644 --- a/matrixssl/matrixsslNet.h +++ b/matrixssl/matrixsslNet.h @@ -32,7 +32,7 @@ #define INCLUDE_GUARD_MATRIXSSLNET_H #include "coreApi.h" -#include "matrixssl/matrixsslApi.h" +#include "matrixssl/matrixsslImpl.h" #include "osdep_stdbool.h" #ifdef USE_PS_NETWORKING diff --git a/matrixssl/matrixsslSocket.c b/matrixssl/matrixsslSocket.c index e868216..3d5a8a0 100644 --- a/matrixssl/matrixsslSocket.c +++ b/matrixssl/matrixsslSocket.c @@ -48,7 +48,7 @@ # define DEBUGF(...) do {} while (0) #endif -#ifdef USE_PS_NETWORKING +#if defined(USE_PS_NETWORKING) && defined(MATRIX_USE_FILE_SYSTEM) /* The flags used by this program for TLS versions. */ # define FLAG_TLS_1_0 (1 << 10) @@ -155,9 +155,11 @@ static int init_client_tls(psSocket_t *sock, const char *capath, int tls) # else # ifdef USE_ECC rc = matrixSslLoadEcKeys(keys, NULL, NULL, NULL, capath); +# else # warning either USE_RSA or USE_ECC needed in matrixsslSocket.c # endif # endif + if (rc != PS_SUCCESS) { DEBUGF("No certificate material loaded.\n"); @@ -510,6 +512,6 @@ const psSocketFunctions_t *psGetSocketFunctionsTLS(void) return &psSocketFunctionsTLS; } -#endif /* USE_PS_NETWORKING */ +#endif /* USE_PS_NETWORKING && MATRIX_USE_FILE_SYSTEM */ /* end of file matrixsslSocket.c */ diff --git a/matrixssl/matrixssllib.h b/matrixssl/matrixssllib.h index 9012279..12b4a5a 100644 --- a/matrixssl/matrixssllib.h +++ b/matrixssl/matrixssllib.h @@ -280,7 +280,9 @@ extern "C" { /* matrixSslSetSessionOption defines */ -# define SSL_OPTION_FULL_HANDSHAKE 1 +# ifndef SSL_OPTION_FULL_HANDSHAKE +# define SSL_OPTION_FULL_HANDSHAKE 1 +# endif # ifdef USE_CLIENT_AUTH # define SSL_OPTION_DISABLE_CLIENT_AUTH 2 # define SSL_OPTION_ENABLE_CLIENT_AUTH 3 @@ -288,56 +290,8 @@ extern "C" { # define SSL_OPTION_DISABLE_REHANDSHAKES 4 # define SSL_OPTION_REENABLE_REHANDSHAKES 5 -/* - Use as return code in user validation callback to allow - anonymous connections to proceed. - MUST NOT OVERLAP WITH ANY OF THE ALERT CODES ABOVE - */ -# define SSL_ALLOW_ANON_CONNECTION 254 - -/* Internal values for ssl_t.flags */ -# define SSL_FLAGS_SERVER (1U << 0) -# define SSL_FLAGS_READ_SECURE (1U << 1) -# define SSL_FLAGS_WRITE_SECURE (1U << 2) -# define SSL_FLAGS_RESUMED (1U << 3) -# define SSL_FLAGS_CLOSED (1U << 4) -# define SSL_FLAGS_NEED_ENCODE (1U << 5) -# define SSL_FLAGS_ERROR (1U << 6) -# define SSL_FLAGS_CLIENT_AUTH (1U << 7) -# define SSL_FLAGS_ANON_CIPHER (1U << 8) -# define SSL_FLAGS_FALSE_START (1U << 9) -# define SSL_FLAGS_SSLV3 (1U << 10) -# define SSL_FLAGS_TLS (1U << 11) -# define SSL_FLAGS_TLS_1_0 SSL_FLAGS_TLS /* For naming consistency */ -# define SSL_FLAGS_TLS_1_1 (1U << 12) -# define SSL_FLAGS_TLS_1_2 (1U << 13) -# define SSL_FLAGS_DTLS (1U << 14) -# define SSL_FLAGS_DHE_WITH_RSA (1U << 15) -# define SSL_FLAGS_DHE_WITH_DSA (1U << 16) -# define SSL_FLAGS_DHE_KEY_EXCH (1U << 17) -# define SSL_FLAGS_PSK_CIPHER (1U << 18) -# define SSL_FLAGS_ECC_CIPHER (1U << 19) -# define SSL_FLAGS_AEAD_W (1U << 20) -# define SSL_FLAGS_AEAD_R (1U << 21) -# define SSL_FLAGS_NONCE_W (1U << 22) -# define SSL_FLAGS_NONCE_R (1U << 23) -# define SSL_FLAGS_HTTP2 (1U << 24) -# define SSL_FLAGS_TLS_1_3 (1U << 25) -# define SSL_FLAGS_TLS_1_3_DRAFT_22 (1U << 26) -# define SSL_FLAGS_TLS_1_3_DRAFT_23 (1U << 27) -# define SSL_FLAGS_TLS_1_3_DRAFT_24 (1U << 28) -# define SSL_FLAGS_TLS_1_3_DRAFT_26 (1U << 29) -# define SSL_FLAGS_TLS_1_3_DRAFT_28 (1U << 30) -# define SSL_FLAGS_TLS_1_3_NEGOTIATED (1U << 31) -/* - The following conflict with TLS 1.3 flags, but interceptor - and EAP_FAST are not allowed with USE_TLS_1_3. -# ifdef TODO*/ -# define SSL_FLAGS_INTERCEPTOR (1U << 26) -# define SSL_FLAGS_EAP_FAST (1U << 27) - -# define IS_SERVER(SSL) ((SSL->flags & SSL_FLAGS_SERVER) ? PS_TRUE : PS_FALSE) -# define IS_CLIENT(SSL) !IS_SERVER(SSL) +# define MATRIX_IS_SERVER(SSL) ((SSL->flags & SSL_FLAGS_SERVER) ? PS_TRUE : PS_FALSE) +# define MATRIX_IS_CLIENT(SSL) !MATRIX_IS_SERVER(SSL) # include "matrixssllib_version.h" # include "matrixssllib_secconfig.h" @@ -352,6 +306,34 @@ extern "C" { # define DECRYPTING_WITH_CHACHA20(SSL) PS_TRUE # endif +/******************************************************************************/ + +/* Internal values for ssl_t.flags */ +# define SSL_FLAGS_SERVER (1U << 0) +# define SSL_FLAGS_READ_SECURE (1U << 1) +# define SSL_FLAGS_WRITE_SECURE (1U << 2) +# define SSL_FLAGS_RESUMED (1U << 3) +# define SSL_FLAGS_CLOSED (1U << 4) +# define SSL_FLAGS_NEED_ENCODE (1U << 5) +# define SSL_FLAGS_ERROR (1U << 6) +# define SSL_FLAGS_CLIENT_AUTH (1U << 7) +# define SSL_FLAGS_ANON_CIPHER (1U << 8) +# define SSL_FLAGS_FALSE_START (1U << 9) +/* 10 to 15 are public version flags, defined in matrixSslApiVer.h) */ +# define SSL_FLAGS_DHE_WITH_RSA (1U << 16) +# define SSL_FLAGS_DHE_WITH_DSA (1U << 17) +# define SSL_FLAGS_DHE_KEY_EXCH (1U << 18) +# define SSL_FLAGS_PSK_CIPHER (1U << 19) +# define SSL_FLAGS_ECC_CIPHER (1U << 20) +# define SSL_FLAGS_AEAD_W (1U << 21) +# define SSL_FLAGS_AEAD_R (1U << 22) +# define SSL_FLAGS_NONCE_W (1U << 23) +# define SSL_FLAGS_NONCE_R (1U << 24) +# define SSL_FLAGS_HTTP2 (1U << 25) +/* 26 to 31 are public version flags, defined in matrixSslApiVer.h) */ +# define SSL_FLAGS_INTERCEPTOR (1U << 26) +# define SSL_FLAGS_EAP_FAST (1U << 27) + /* Internal flags for ssl_t.hwflags */ # define SSL_HWFLAGS_HW (1 << 0) /* Use HW for decode/encode */ # define SSL_HWFLAGS_HW_SW (1 << 1) /* Use HW & SW in parallel (debug) */ @@ -551,9 +533,6 @@ static inline uint16_t HASH_SIG_MASK(uint8_t hash, uint8_t sig) } # endif /* USE_TLS_1_2 */ -/* Additional ssl alert value, indicating no error has ocurred. */ -# define SSL_ALERT_NONE 255/* No error */ - /* SSL/TLS protocol message sizes */ # define SSL_HS_RANDOM_SIZE 32 # define SSL_HS_RSA_PREMASTER_SIZE 48 @@ -607,112 +586,6 @@ static inline uint16_t HASH_SIG_MASK(uint8_t hash, uint8_t sig) # error Unexpected TLS Version # endif -/* Cipher suite specification IDs, in numerical order. */ -# define SSL_NULL_WITH_NULL_NULL 0x0000 -# define SSL_RSA_WITH_NULL_MD5 0x0001 -# define SSL_RSA_WITH_NULL_SHA 0x0002 -# define SSL_RSA_WITH_RC4_128_MD5 0x0004 -# define SSL_RSA_WITH_RC4_128_SHA 0x0005 -# define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007 -# define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000A /* 10 */ -# define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 /* 22 */ -# define SSL_DH_anon_WITH_RC4_128_MD5 0x0018 /* 24 */ -# define SSL_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B /* 27 */ -# define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F /* 47 */ -# define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 /* 51 */ -# define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 /* 52 */ -# define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 /* 53 */ -# define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 /* 57 */ -# define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A /* 58 */ -# define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C /* 60 */ -# define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D /* 61 */ -# define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 /* 103 */ -# define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B /* 107 */ -# define TLS_RSA_WITH_SEED_CBC_SHA 0x0096 /* 150 */ -# define TLS_PSK_WITH_AES_128_CBC_SHA 0x008C /* 140 */ -# define TLS_PSK_WITH_AES_128_CBC_SHA256 0x00AE /* 174 */ -# define TLS_PSK_WITH_AES_256_CBC_SHA384 0x00AF /* 175 */ -# define TLS_PSK_WITH_AES_256_CBC_SHA 0x008D /* 141 */ -# define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x0090 /* 144 */ -# define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x0091 /* 145 */ -# define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C /* 156 */ -# define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D /* 157 */ -# define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F /* 159 */ - -# define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF /**< @see RFC 5746 */ -# define TLS_FALLBACK_SCSV 0x5600 /**< @see RFC 7507 */ - -# define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /* 49156 */ -# define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /* 49157 */ -# define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /* 49161 */ -# define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /* 49162 */ -# define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /* 49170 */ -# define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /* 49171 */ -# define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /* 49172 */ -# define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /* 49166 */ -# define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /* 49167 */ -# define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /* 49187 */ -# define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /* 49188 */ -# define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /* 49189 */ -# define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /* 49190 */ -# define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /* 49191 */ -# define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /* 49192 */ -# define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /* 49193 */ -# define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /* 49194 */ -# define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /* 49195 */ -# define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /* 49196 */ -# define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /* 49197 */ -# define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /* 49198 */ -# define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /* 49199 */ -# define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /* 49200 */ -# define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /* 49201 */ -# define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /* 49202 */ -/* Defined in https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305 */ -# define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /* 52392 */ -# define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /* 52393 */ -/* TLS 1.3 ciphersuites. */ -# define TLS_AES_128_GCM_SHA256 0x1301 /* 4865 */ -# define TLS_AES_256_GCM_SHA384 0x1302 /* 4866 */ -# define TLS_CHACHA20_POLY1305_SHA256 0x1303 /* 4867 */ -# define TLS_AES_128_CCM_SHA_256 0x1304 /* 4868 */ -# define TLS_AES_128_CCM_8_SHA256 0x1305 /* 4869 */ - - -/* - Supported HELLO extensions - Extension status stored by bitfield in ssl_t.extFlags - @see https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml - */ -# define EXT_SNI 0 -# define EXT_SERVER_NAME 0 /* SNI renamed in TLS 1.3 */ -# define EXT_MAX_FRAGMENT_LEN 1 -# define EXT_TRUSTED_CA_KEYS 3 -# define EXT_TRUNCATED_HMAC 4 -# define EXT_STATUS_REQUEST 5 /* OCSP */ -# define EXT_ELLIPTIC_CURVE 10 /* Client-send only */ -# define EXT_SUPPORTED_GROUPS 10 /* ELLIPTIC_CURVE renamed in 1.3 */ -# define EXT_ELLIPTIC_POINTS 11 -# define EXT_SIGNATURE_ALGORITHMS 13 -# define EXT_ALPN 16 -# define EXT_SIGNED_CERTIFICATE_TIMESTAMP 18 -# define EXT_EXTENDED_MASTER_SECRET 23 -# define EXT_SESSION_TICKET 35 -# define EXT_KEY_SHARE_PRE_DRAFT_23 40 /* Up to 1.3 draft 22 */ -# define EXT_PRE_SHARED_KEY 41 -# define EXT_EARLY_DATA 42 -# define EXT_SUPPORTED_VERSIONS 43 -# define EXT_COOKIE 44 -# define EXT_PSK_KEY_EXCHANGE_MODES 45 -# define EXT_CERTIFICATE_AUTHORITIES 47 -# define EXT_OID_FILTERS 48 -# define EXT_POST_HANDSHAKE_AUTH 49 -# define EXT_SIGNATURE_ALGORITHMS_CERT 50 -# define EXT_KEY_SHARE 51 /* Since 1.3 draft 23. */ -# define EXT_RENEGOTIATION_INFO 0xFF01 - -/* How large the ALPN extension arrary is. Number of protos client can talk */ -# define MAX_PROTO_EXT 8 - /* Maximum key block size for any defined cipher This must be validated if new ciphers are added @@ -761,105 +634,6 @@ struct ssl; typedef psBuf_t sslBuf_t; -/** Type of the expectedName parameter (expected peer identity) - that is passed to matrixValidateCerts or matrixSslNewClientSession. - These can be used to specify the field in the peer certificate - against which expectedName is to be matched. */ -typedef enum -{ - NAME_TYPE_ANY = 0, /* Default. Checked against everything listed below. - This option exists for compatibility with earlier - versions, where no attempt was made to distinguish - between different types of expectedNames. - New applications should prefer to pick one of the - more specific types below. */ - NAME_TYPE_HOSTNAME, /* Checked against the dNSName field and the - subject commonName. This is the default. */ - NAME_TYPE_CN, /* Checked against the subject commonName. - Note that by default, the subject commonName will only - be checked when there are no supported fields - in the SAN. The flag - VCERTS_MFLAG_ALWAYS_CHECK_SUBJECT_CN can be used - to force a commonName check. */ - NAME_TYPE_SAN_DNS, /* Checked against the dNSName field. */ - NAME_TYPE_SAN_EMAIL, /* Checked against the rfc822Name field. */ - NAME_TYPE_SAN_IP_ADDRESS, /* Checked against the iPAddress field. */ -} expectedNameType_t; - -/** This struct can be used to pass additional options - to matrixValidateCertsExt */ -typedef struct -{ - expectedNameType_t nameType; /* Type of expectedName. */ - uint64_t flags; /* General flags for controling the validation - prodecure. The allowed flags have the - VCERTS_FLAG_ prefix. */ - uint32_t mFlags; /* Flags for controlling how expectedName should - be matched. The allowed flags have the - USE VCERTS_MFLAG prefix. */ - int32_t max_verify_depth; /* Maximum allowed depth for the peer's - cert chain. 0 : unrestricted, - 1: only a single (self-signed) cert allowed, - 2: peer cert + 1 root CA - 3: peer cert + 1 CA + 1 root CA, etc. */ -} matrixValidateCertsOptions_t; - -/* flags for matrixValidateCertsOptions_t: */ -/** - Validate the expectedName argument against a subset of the - GeneralName rules for DNS, Email and IP types _before_ trying - to find for expectedName in the cert. Note that this is only - applicable if expectedName is a GeneralName, i.e. when using - any of the VCERTS_MFLAG_SAN flags. - */ -# define VCERTS_FLAG_VALIDATE_EXPECTED_GENERAL_NAME 0x01 - -/** - Skip the expectedName matching. This is useful e.g. when - matrixValidateCerts is called by the TLS server to validate - a client certificate. The client name is usually not known - in this case. - */ -# define VCERTS_FLAG_SKIP_EXPECTED_NAME_VALIDATION 0x02 - -/** - Enable matrixValidateCertsExt to perform an independent validation - of the certificate date ranges. Dates of the subject cert chain - and the found issuer cert are validated against the current - system time. - - By default, MatrixSSL only checks the certificate date validity - during certificate parsing, setting the PS_CERT_AUTH_FAIL_DATE_FLAG - flag in cert->authFailFlags when date validation fails. This flag - will be noticed by matrixValidateCertsExt (but only for subject - certs, not the found issuer cert). In some applications, the delay - between parsing and the actual chain validation can be long. In such - situations, it is useful to re-perform the date validation - in matrixValidateCertsExt. -*/ -# define VCERTS_FLAG_REVALIDATE_DATES 0x04 - -/* mFlags for matrixValidateCertsOptions_t: */ -/** - If expectedName is a hostname, always attempt to match it - with the subject CN, even if a supported, but non-matching - subjectAltName was presented. - Without this flag, the CN is checked only when no supported SAN - was presented. This default behaviour is in accordance with - Section 6.4.4 of RFC 6125, and this flag overrides it. - */ -# define VCERTS_MFLAG_ALWAYS_CHECK_SUBJECT_CN 0x01 - -/** - Use case-insensitive match for the the whole email address - in the rfc822Name field of the SAN. Without this flag, - case-sensitive matching is used for the local-part and - case-insensitive matching for the host-part, in accordance - with RFC 5280. - This flag requires VCERTS_MFLAG_SAN_MATCH_RFC822NAME. - */ -# define VCERTS_MFLAG_SAN_EMAIL_CASE_INSENSITIVE_LOCAL_PART 0x02 - /******************************************************************************/ # ifdef USE_PSK_CIPHER_SUITE @@ -1020,63 +794,6 @@ struct sslKeys # endif }; -/******************************************************************************/ -/* Type to pass optional features to NewSession calls */ -struct sslSessOpts -{ - short ticketResumption; /* Client: 1 to use. Server N/A */ - short maxFragLen; /* Client: 512 etc.. Server: -1 to disable */ - short truncHmac; /* Client: 1 to use. Server: -1 to disable */ - short extendedMasterSecret; /* On by default. -1 to disable */ - short trustedCAindication; /* Client: 1 to use */ - short fallbackScsv; /* Client: 1 to use */ -# if defined(USE_OCSP_RESPONSE) || defined(USE_OCSP_REQUEST) - short OCSPstapling; /* Client: 1 to send status_request */ -# endif -# ifdef USE_ECC - int32 ecFlags; /* Elliptic curve set (SSL_OPT_SECP192R1 etc.) */ -# endif -# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING - int32 useExtCvSigOp; /* Client: sign the handshake messages hash in - CertificateVerify externally. */ -# endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ - int32 versionFlag; /* The SSL_FLAGS_TLS_ version (+ DTLS flag here) */ - uint32_t supportedVersions[TLS_MAX_SUPPORTED_VERSIONS]; /* Priority list of supported protocol versions*/ - psSize_t supportedVersionsLen; -# ifdef USE_TLS_1_3 - uint16_t tls13SupportedSigAlgsCert[TLS_MAX_SIGNATURE_ALGORITHMS]; - psSize_t tls13SupportedSigAlgsCertLen; - psSize_t tls13SessionMaxEarlyData; /* For server this defines what is the max early - data value for the new session tickets. Not used - for clients. */ -# endif - void *userPtr; /* Initial value of ssl->userPtr during NewSession */ - void *memAllocPtr; /* Will be passed to psOpenPool for each call - related to this session */ - psPool_t *bufferPool; /* Optional mem pool for inbuf and outbuf */ - int32 keep_peer_cert_der; /* Keep raw DER of peer certs */ - int32 keep_peer_certs; /* Keep peer cert chain until the session - is deleted */ - matrixValidateCertsOptions_t validateCertsOpts; /* Certificate validation - options. */ - void *userDataPtr; /* Initial value of ssl->userDataPtr during NewSession. */ - uint16_t tls13SupportedGroups[TLS_1_3_MAX_GROUPS]; - psSize_t tls13SupportedGroupsLen; - psSize_t tls13NumClientHelloKeyShares; - uint16_t supportedSigAlgs[TLS_MAX_SIGNATURE_ALGORITHMS]; - psSize_t supportedSigAlgsLen; - psSizeL_t tls13PadLen; - psSizeL_t tls13BlockSize; - psBool_t tls13CiphersuitesEnabledClient; - /* Minimum DH modulus size the client is willing to accept - from the server in ServerKeyExchange. This setting - affects client-side handshake behaviour only. Server-side - DH parameters are determined during key loading. - The global compile-time setting MIN_DH_BITS is the minimum - size of DH parameters MatrixSSL is allowed to load. */ - psSize_t minDhBits; -}; - /******************************************************************************/ /* SSL record and session structures @@ -1105,6 +822,7 @@ typedef struct { unsigned char clientRandom[SSL_HS_RANDOM_SIZE]; /* From ClientHello */ unsigned char serverRandom[SSL_HS_RANDOM_SIZE]; /* From ServerHello */ + unsigned char masterSecret[SSL_HS_MASTER_SIZE]; unsigned char *premaster; /* variable size */ psSize_t premasterSize; @@ -1164,6 +882,7 @@ typedef struct psTls13Psk_t *tls13ChosenPsk; uint16_t tls13SelectedIdentityIndex; psBool_t tls13UsingPsk; + psBool_t tls13DidEncodePsk; /* True if we offered a PSK in CH. */ psSize_t tls13BindersLen; const unsigned char *tls13CHStart; psSizeL_t tls13CHLen; @@ -1271,8 +990,12 @@ typedef struct psEccKey_t *eccKeyPriv; /* local key */ psEccKey_t *eccKeyPub; /* remote key */ psPool_t *eccDhKeyPool; /* handshake-scope pool for clients */ - unsigned char *x25519KeyPub; -# endif +# ifdef USE_X25519 + psCurve25519Key_t x25519KeyPriv; /* local key */ + unsigned char *x25519KeyPub; /* remote key */ +# endif /* USE_X25519 */ + uint16_t peerCurveId; +# endif /* USE_ECC_CIPHER_SUITE */ # ifdef USE_TLS_1_3 psPubKey_t *tls13KeyAgreeKeys[TLS_1_3_MAX_GROUPS]; # endif @@ -1318,7 +1041,7 @@ enum sessionTicketState_e # endif /* Used by user code to store cached session info after the ssl_t is closed */ -struct sslSessionId +typedef struct sslSessionId { psPool_t *pool; unsigned char id[SSL_MAX_SESSION_ID_SIZE]; @@ -1333,7 +1056,7 @@ struct sslSessionId # ifdef USE_TLS_1_3 psTls13Psk_t *psk; # endif -}; +} sslSessionId_t; /* Used internally by the session cache table to store session parameters */ typedef struct @@ -1350,13 +1073,13 @@ typedef struct } sslSessionEntry_t; /* Used by user code to define custom hello extensions */ -typedef struct tlsHelloExt +typedef struct tlsExtension { psPool_t *pool; int32 extType; uint32 extLen; unsigned char *extData; - struct tlsHelloExt *next; + struct tlsExtension *next; } tlsExtension_t; /* Hold the info needed to perform a public key operation for flight writes @@ -1413,6 +1136,11 @@ struct ssl sslSec_t sec; /* Security structure */ sslKeys_t *keys; /* SSL public and private - keys confiured. */ +# ifdef USE_BUFFERED_HS_HASH + psBuf_t hsMsgBuf; + psSizeL_t hsMsgCHtoCKELen; +# endif /* USE_BUFFERED_HS_HASH */ + # ifdef USE_IDENTITY_CERTIFICATES sslIdentity_t *chosenIdentity; /* Keys chosen for authentication */ # endif @@ -1464,6 +1192,10 @@ struct ssl tlsExtension_t *userExt; /* User provided extensions from session options. Stored here for reuse in renegotiations and in responses to TLS 1.3 HRRs. */ +# if defined(USE_CLIENT_SIDE_SSL) && defined(ENABLE_SECURE_REHANDSHAKES) + psCipher16_t *tlsClientCipherSuites; + uint8_t tlsClientCipherSuitesLen; +# endif # ifdef USE_SERVER_SIDE_SSL uint16 disabledCiphers[SSL_MAX_DISABLED_CIPHERS]; sniCb_t sni_cb; @@ -1647,7 +1379,7 @@ struct ssl # ifdef USE_DTLS # ifdef USE_SERVER_SIDE_SSL - unsigned char srvCookie[DTLS_COOKIE_SIZE]; /* server can avoid allocs */ + unsigned char srvCookie[DTLS_COOKIE_SIZE]; /* server can avoid allocs */ # endif # ifdef USE_CLIENT_SIDE_SSL unsigned char *cookie; /* hello_verify_request cookie */ @@ -1687,6 +1419,7 @@ struct ssl unsigned char oenIvSize; unsigned char oenBlockSize; unsigned char owriteIV[16]; /* GCM uses this in the nonce */ + unsigned char owriteKey[SSL_MAX_SYM_KEY_SIZE]; # ifdef USE_NATIVE_TLS_ALGS unsigned char owriteMAC[SSL_MAX_MAC_SIZE]; psCipherContext_t oencryptCtx; @@ -1771,7 +1504,7 @@ struct ssl related to this session */ void *userPtr; void *userDataPtr; -}; +}; /* End of struct ssl { ... */ typedef struct ssl ssl_t; @@ -1783,38 +1516,65 @@ static const unsigned char sha256OfHelloRetryRequest[] = 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c }; - #endif /* USE_TLS_1_3 */ + /******************************************************************************/ /* Former public APIS in 1.x and 2.x. Now deprecated in 3.x These functions are still heavily used internally, just no longer publically supported. */ -extern int32 matrixSslDecode(ssl_t *ssl, unsigned char **buf, uint32 *len, - uint32 size, uint32 *remaining, uint32 *requiredLen, - int32 *error, unsigned char *alertLevel, - unsigned char *alertDescription); -extern int32 matrixSslEncode(ssl_t *ssl, unsigned char *buf, uint32 size, - unsigned char *ptBuf, uint32 *len); -extern int32 matrixSslGetEncodedSize(ssl_t *ssl, uint32 len); -extern void matrixSslSetCertValidator(ssl_t *ssl, sslCertCb_t certValidator); -extern int32 matrixSslNewSession(ssl_t **ssl, const sslKeys_t *keys, - sslSessionId_t *session, sslSessOpts_t *options); -extern void matrixSslSetSessionOption(ssl_t *ssl, int32 option, void *arg); -extern int32_t matrixSslHandshakeIsComplete(const ssl_t *ssl); -extern psBool_t matrixSslRehandshaking(const ssl_t *ssl); +extern int32 matrixSslDecode( + ssl_t *ssl, + unsigned char **buf, + uint32 *len, + uint32 size, + uint32 *remaining, + uint32 *requiredLen, + int32 *error, + unsigned char *alertLevel, + unsigned char *alertDescription); +extern int32 matrixSslEncode( + ssl_t *ssl, + unsigned char *buf, + uint32 size, + unsigned char *ptBuf, + uint32 *len); +extern int32 matrixSslGetEncodedSize( + ssl_t *ssl, + uint32 len); +extern void matrixSslSetCertValidator( + ssl_t *ssl, + sslCertCb_t certValidator); +extern int32 matrixSslNewSession( + ssl_t **ssl, + const sslKeys_t *keys, + sslSessionId_t *session, + sslSessOpts_t *options); +extern void matrixSslSetSessionOption( + ssl_t *ssl, + int32 option, + void *arg); +extern psBool_t matrixSslRehandshaking( + const ssl_t *ssl); /* This used to be prefixed with 'matrix' */ -extern int32 sslEncodeClosureAlert(ssl_t *ssl, sslBuf_t *out, - uint32 *reqLen); - -extern int32 matrixSslEncodeHelloRequest(ssl_t *ssl, sslBuf_t *out, - uint32 *reqLen); -extern int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, - const psCipher16_t cipherSpec[], uint8_t cipherSpecLen, - uint32 *requiredLen, tlsExtension_t *userExt, - sslSessOpts_t *options); +extern int32 sslEncodeClosureAlert( + ssl_t *ssl, + sslBuf_t *out, + uint32 *reqLen); +extern int32 matrixSslEncodeHelloRequest( + ssl_t *ssl, + sslBuf_t *out, + uint32 *reqLen); +extern int32_t matrixSslEncodeClientHello( + ssl_t *ssl, + sslBuf_t *out, + const psCipher16_t cipherSpec[], + uint8_t cipherSpecLen, + uint32 *requiredLen, + tlsExtension_t *userExt, + sslSessOpts_t *options); # ifdef USE_CLIENT_SIDE_SSL extern int32 matrixSslGetSessionId(ssl_t *ssl, sslSessionId_t *sessionId); @@ -1837,6 +1597,14 @@ PSPUBLIC void matrixSslAddRehandshakeCredits(ssl_t *ssl, int32 credits); PSPUBLIC int32 matrixSslIsSessionCompressionOn(ssl_t *ssl); # endif +# ifdef USE_ECC +int32_t matrixSslGenEphemeralEcKey( + sslKeys_t *keys, + psEccKey_t *ecc, + const psEccCurve_t *curve, + void *hwCtx); +# endif + # ifdef USE_TLS_1_3 static inline psBool_t tls13IsResumedHandshake(ssl_t *ssl) @@ -1879,13 +1647,6 @@ psBool_t isResumedHandshake(ssl_t *ssl) */ # ifndef USE_ONLY_PSK_CIPHER_SUITE -extern int32 matrixValidateCerts(psPool_t *pool, psX509Cert_t *subjectCerts, - psX509Cert_t *issuerCerts, char *expectedName, - psX509Cert_t **foundIssuer, void *pkiData, void *userPoolPtr); -extern int32 matrixValidateCertsExt(psPool_t *pool, psX509Cert_t *subjectCerts, - psX509Cert_t *issuerCerts, char *expectedName, - psX509Cert_t **foundIssuer, void *pkiData, void *userPoolPtr, - const matrixValidateCertsOptions_t *options); extern int32 matrixUserCertValidator(ssl_t *ssl, int32 alert, psX509Cert_t *subjectCert, sslCertCb_t certCb); # endif /* USE_ONLY_PSK_CIPHER_SUITE */ @@ -1965,7 +1726,10 @@ extern int32 sslActivateReadCipher(ssl_t *ssl); extern int32 sslActivateWriteCipher(ssl_t *ssl); extern int32_t sslUpdateHSHash(ssl_t *ssl, const unsigned char *in, psSize_t len); extern int32 sslInitHSHash(ssl_t *ssl); -extern int32 sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, int32 senderFlag); +extern int32 sslSnapshotHSHash(ssl_t *ssl, + unsigned char *out, + psBool_t sender, + psBool_t isFinishedHash); extern int32_t findFromUint16Array(const uint16_t *a, psSize_t aLen, const uint16_t b); @@ -1992,12 +1756,15 @@ extern int32_t tlsVerify(ssl_t *ssl, extern psRes_t tlsPrepareSkeSignature(ssl_t *ssl, int32_t skeSigAlg, unsigned char *tbsStart, - unsigned char *c); + unsigned char *c, + psBool_t needPreHash); extern psRes_t tlsMakeSkeSignature(ssl_t *ssl, pkaAfter_t *pka, psBuf_t *out); +# ifdef USE_IDENTITY_CERTIFICATES extern int32_t chooseSkeSigAlg(ssl_t *ssl, sslIdentity_t *id); +# endif extern int accountForEcdsaSizeChange(ssl_t *ssl, pkaAfter_t *pka, int real, @@ -2360,6 +2127,7 @@ extern void clearPkaAfter(ssl_t *ssl); extern pkaAfter_t *getPkaAfter(ssl_t *ssl); extern void freePkaAfter(ssl_t *ssl); extern void clearFlightList(ssl_t *ssl); +extern void sslFreeHSHash(ssl_t *ssl); # ifdef USE_SERVER_SIDE_SSL extern int32 matrixRegisterSession(ssl_t *ssl); @@ -2669,11 +2437,13 @@ void matrixsslUpdateStat(ssl_t *ssl, int32_t type, int32_t value) # ifndef USE_SSL_INFORMATIONAL_TRACE # define psTraceInfo(x) +# define psTraceInfoIndent(x, y) # define psTraceStrInfo(x, y) # define psTraceIntInfo(x, y) # else # include "osdep.h" # define psTraceInfo(x) tlsTrace(x) +# define psTraceInfoIndent(x, y) tlsTraceIndent(x, y) # define psTraceStrInfo(x, y) tlsTraceStr(x, y) # define psTraceIntInfo(x, y) tlsTraceInt(x, y) # endif /* USE_SSL_INFORMATIONAL_TRACE */ @@ -2756,6 +2526,8 @@ void psPrintCipherList(psSize_t indentLevel, const psCipher16_t *cipherList, psSize_t numCiphers, psBool_t addNewline); +void psPrintPubKeyTypeAndSize(ssl_t *ssl, + psPubKey_t *authKey); void psPrintSigAlgs(psSize_t indentLevel, const char *where, uint16_t sigAlgs, @@ -2763,10 +2535,16 @@ void psPrintSigAlgs(psSize_t indentLevel, void psPrintTls13SigAlg(psSize_t indentLevel, const char *where, uint16_t alg, + psBool_t bigEndian, psBool_t addNewline); void psPrintTls13SigAlgList(psSize_t indentLevel, const char *where, - uint16_t *algs, + const uint16_t *algs, + psSize_t numAlgs, + psBool_t addNewline); +void psPrintTls13SigAlgListBigEndian(psSize_t indentLevel, + const char *where, + const uint16_t *algs, psSize_t numAlgs, psBool_t addNewline); void psPrintProtocolVersionNew(psSize_t indentLevel, @@ -2802,6 +2580,11 @@ void psPrintTls13NamedGroupList(psSize_t indentLevel, psSize_t listLen, ssl_t *ssl, psBool_t addNewline); +void psPrintEcFlags(psSize_t indentLevel, + const char *where, + uint32_t ecFlags, + ssl_t *ssl, + psBool_t addNewline); void psPrintServerName(psSize_t indentLevel, const char *where, const char *serverName, @@ -2846,10 +2629,12 @@ void psPrintTranscriptHashUpdate(ssl_t *ssl, psPrintSigAlgs(indentLevel, sigAlgs, where, addNewline) # define psTracePrintPubKeyTypeAndSize(ssl, key) \ psPrintPubKeyTypeAndSize(ssl, key) -# define psTracePrintTls13SigAlg(indentLevel, where, alg, addNewline) \ - psPrintTls13SigAlg(indentLevel, where, alg, addNewline) +# define psTracePrintTls13SigAlg(indentLevel, where, alg, bigEndian, addNewline) \ + psPrintTls13SigAlg(indentLevel, where, alg, bigEndian, addNewline) # define psTracePrintTls13SigAlgList(indentLevel, where, algs, numAlgs, addNewline) \ psPrintTls13SigAlgList(indentLevel, where, algs, numAlgs, addNewline) +# define psTracePrintTls13SigAlgListBigEndian(indentLevel, where, algs, numAlgs, addNewline) \ + psPrintTls13SigAlgListBigEndian(indentLevel, where, algs, numAlgs, addNewline) # define psTracePrintProtocolVersion(indentLevel, where, majVer, minVer, addNewline) \ psPrintProtocolVersion(indentLevel, where, majVer, minVer, addNewline) # define psTracePrintProtocolVersionNew(indentLevel, where, ver, addNewline) \ @@ -2864,6 +2649,8 @@ void psPrintTranscriptHashUpdate(ssl_t *ssl, psPrintTls13NamedGroup(indentLevel, where, curveId, addNewline) # define psTracePrintTls13NamedGroupList(indentLevel, where, list, listLen, ssl, addNewline) \ psPrintTls13NamedGroupList(indentLevel, where, list, listLen, ssl, addNewline) +# define psTracePrintEcFlags(indentLevel, where, ecFlags, ssl, addNewline) \ + psPrintEcFlags(indentLevel, where, ecFlags, ssl, addNewline) # define psTracePrintServerName(indentLevel, where, serverName, addNewline) \ psPrintServerName(indentLevel, where, serverName, addNewline) # define psTracePrintTlsKeys(where, ssl, addNewline) \ @@ -2893,8 +2680,9 @@ void psPrintTranscriptHashUpdate(ssl_t *ssl, # define psTracePrintCipherList(indentLevel, where, cipherList, numCiphers, addNewline) # define psTracePrintSigAlgs(indentlevel, sigAlgs, where, addNewLine) # define psTracePrintPubKeyTypeAndSize(ssl, key) -# define psTracePrintTls13SigAlg(indentLevel, where, sigAlg, addNewline) +# define psTracePrintTls13SigAlg(indentLevel, where, sigAlg, bigEndian, addNewline) # define psTracePrintTls13SigAlgList(indentLevel, where, algs, numAlg, addNewline) +# define psTracePrintTls13SigAlgListBigEndian(indentLevel, where, algs, numAlg, addNewline) # define psTracePrintProtocolVersion(indentLevel, where, majVer, minVer, addNewline) # define psTracePrintProtocolVersionNew(indentLevel, where, ver, addNewline) # define psTracePrintNegotiatedProtocolVersion(indentLevel, where, ssl, addNewline) @@ -2903,6 +2691,7 @@ void psPrintTranscriptHashUpdate(ssl_t *ssl, # define psTracePrintSupportedVersionsList(indentLevel, where, ssl, peer, addNewline) # define psTracePrintTls13NamedGroup(indentLevel, where, curveId, addNewline) # define psTracePrintTls13NamedGroupList(indentLevel, where, list, listLen, ssl, addNewline) +# define psTracePrintEcFlags(indentLevel, where, ecFlags, ssl, addNewline) # define psTracePrintServerName(indentLevel, where, serverName, addNewline) # define psTracePrintTlsKeys(where, ssl, addNewline) # define psTracePrintSslFlags(ssl) @@ -2926,6 +2715,7 @@ psBool_t canUseSigAlg(int32_t sigAlg, uint16_t peerSigAlgs); int32_t upgradeSigAlg(int32_t sigAlg, int32_t pubKeyAlgorithm); int32_t chooseSigAlgInt(int32_t certSigAlg, + psPubKey_t *privKey, psSize_t keySize, int32_t pubKeyAlgorithm, uint16_t peerSigAlgs); @@ -2936,6 +2726,7 @@ int32_t getSignatureAndHashAlgorithmEncoding(uint16_t sigAlgOid, unsigned char *b1, unsigned char *b2, uint16_t *hashSize); +int32_t tlsSigAlgToMatrix(uint16_t alg); # endif # ifdef USE_CLIENT_SIDE_SSL diff --git a/matrixssl/matrixssllib_version.h b/matrixssl/matrixssllib_version.h index b9f14f7..8cc619d 100644 --- a/matrixssl/matrixssllib_version.h +++ b/matrixssl/matrixssllib_version.h @@ -37,157 +37,9 @@ #ifndef _h_MATRIXSSLLIB_VERSION # define _h_MATRIXSSLLIB_VERSION -/* Official on-the-wire version identifiers. */ -enum PACKED -{ - v_undefined_enc = 0, - v_ssl_3_0_enc = 0x0300, - v_tls_1_0_enc = 0x0301, - v_tls_1_1_enc = 0x0302, - v_tls_1_2_enc = 0x0303, - v_tls_1_3_enc = 0x0304, - v_tls_1_3_draft_22_enc = 0x7f16, - v_tls_1_3_draft_23_enc = 0x7f17, - v_tls_1_3_draft_24_enc = 0x7f18, - v_tls_1_3_draft_26_enc = 0x7f1a, - v_tls_1_3_draft_28_enc = 0x7f1c, - v_dtls_1_0_enc = 0xfeff, - v_dtls_1_2_enc = 0xfefd -}; - -/** A version v can be either: - 1. Supported by the compile-time config - --> if (v & v_compiled_in) - 2. Supported for the current connection - --> if (SUPP_VER(ssl, v)) - 3. The active version - --> if (ACTV_VER(ssl, v)) - 4. The negotiated version - --> if (NGTD_VER(ssl, v)) - - An activated version is the version we are currently following. - This affects e.g. the format of our ClientHello, whether or not - to allow sending early data, and whether to expect the peer's - hello message to have TLS or DTLS style record headers. - - An active version becomes negotiated when we have sufficient - information from the peer to know that it also supports the - version. -*/ - -/** Bits 0 to 23 are reserved for versions. */ -#define VER_MAX_BIT 23 - -/** Bits 24 to 31 are reserved for version attributes. */ -#define VER_ATTRIB_MAX_BIT 31 - -/* MatrixSSL's internal protocol version identifiers. */ -enum PACKED -{ - v_undefined = 0, - - /** Versions. The ordering of the numeric values of the enumerators - MUST correspond to the chronological order in which the - protocol specifications were published, for example: - v_tls_1_1 < v_tls_1_2. This affects e.g. the default - priority order. */ - v_ssl_3_0 = 1ULL << 0, - v_tls_1_0 = 1ULL << 1, - v_tls_1_1 = 1ULL << 2, - v_dtls_1_0 = 1ULL << 3, - v_tls_1_2 = 1ULL << 4, - v_dtls_1_2 = 1ULL << 5, - v_tls_1_3_draft_22 = 1ULL << 6, - v_tls_1_3_draft_23 = 1ULL << 7, - v_tls_1_3_draft_24 = 1ULL << 8, - v_tls_1_3_draft_26 = 1ULL << 9, - v_tls_1_3_draft_28 = 1ULL << 10, - v_tls_1_3 = 1ULL << 11, - - /** Version attributes. */ - v_tls_negotiated = 1ULL << 24, /* Version negotiation complete? */ - - /** Version combinations. */ - - /** Any supported TLS 1.3 draft version. */ - v_tls_1_3_draft_any = (v_tls_1_3_draft_22 - | v_tls_1_3_draft_23 - | v_tls_1_3_draft_24 - | v_tls_1_3_draft_26 - | v_tls_1_3_draft_28), - /** Any supported TLS 1.3 version. */ - v_tls_1_3_any = (v_tls_1_3 - | v_tls_1_3_draft_any), - /** Any supported TLS version. */ - v_tls_any = (v_tls_1_0 | v_tls_1_1 | v_tls_1_2 | v_tls_1_3_any), - /** Any DTLS version. */ - v_dtls_any = (v_dtls_1_0 | v_dtls_1_2), - /** Any supported legacy version (TLS <1.3) */ - v_tls_legacy = (v_tls_1_0 | v_tls_1_1 | v_tls_1_2 | v_dtls_any), - /** Any supported TLS 1.3 version that uses AAD in record encryption. */ - v_tls_1_3_aad = (v_tls_1_3 - | v_tls_1_3_draft_26 - | v_tls_1_3_draft_28), - /** Any supported TLS 1.3 version that uses 51 as key_share ID */ - v_tls_1_3_key_share_51 = (v_tls_1_3 - | v_tls_1_3_draft_23 - | v_tls_1_3_draft_24 - | v_tls_1_3_draft_26 - | v_tls_1_3_draft_28), - /** Any supported version that uses an explicit IV in CBC mode. */ - v_tls_explicit_iv = (v_dtls_1_0 | v_dtls_1_2 | v_tls_1_1 | v_tls_1_2), - /** Any recommended TLS version. TODO: remove draft #28 once the - RFC version becomes widely supported enough. */ - v_tls_recommended = (v_tls_1_2 | v_tls_1_3 | v_tls_1_3_draft_28), - /** Any recommended DTLS version. */ - v_dtls_recommended = v_dtls_1_2, - /** Any version that allows SHA-2 based ciphersuites. */ - v_tls_sha2 = (v_tls_1_2 | v_tls_1_3_any | v_dtls_1_2), - /** Any version that does NOT allow SHA-2 based ciphersuites. */ - v_tls_no_sha2 = (v_ssl_3_0 | v_tls_1_0 | v_tls_1_1 | v_dtls_1_0), - /** Any version that may need the BEAST workaround. */ - v_tls_need_beast_workaround = (v_ssl_3_0 | v_tls_1_0), - /** Any version that uses the unsupported_extension alert. */ - v_tls_with_unsupported_extension_alert = (v_tls_1_2 - | v_dtls_1_2 - | v_tls_1_3_any), - /** Any version that uses HMAC instead of a custom MAC construction. */ - v_tls_with_hmac = (v_tls_any | v_dtls_any), - /** Any version that supports the signature_algorithms extension. */ - v_tls_with_signature_algorithms = (v_tls_1_2 - | v_tls_1_3_any - | v_dtls_1_2), - /** Any version that supports PKCS #1.5 sigs in CV and SKE. */ - v_tls_with_pkcs15_auth = (v_tls_1_2 | v_dtls_1_2), - /** Any version that uses the TLS 1.2 PRF. */ - v_tls_with_tls_1_2_prf = (v_tls_1_2 | v_dtls_1_2), - /** Any version supported by build-time-config. */ - v_compiled_in = (0 -# if !defined(DISABLE_SSLV3) - | v_ssl_3_0 -# endif -# if defined(USE_TLS) && !defined(DISABLE_TLS_1_0) - | v_tls_1_0 -# endif -# if defined(USE_TLS_1_1) && !defined(DISABLE_TLS_1_1) - | v_tls_1_1 -# if defined(USE_DTLS) - | v_dtls_1_0 -# endif -# endif -# if defined(USE_TLS_1_2) && !defined(DISABLE_TLS_1_2) - | v_tls_1_2 -# if defined(USE_DTLS) - | v_dtls_1_2 -# endif -# endif -# if defined(USE_TLS_1_3) && !defined(DISABLE_TLS_1_3) - | v_tls_1_3_any -# endif - ) -}; - /* + Note: psProtocolVersion_t values are defined in matrixsslApi.h. + Note: we could store all version lists as a single variable. But typically the version lists imply priority order. There is no easy way to store priority order in a flag variable. @@ -309,7 +161,7 @@ psProtocolVersion_t psFlagToVer(int32_t flag); { \ (ssl)->activeVersion = (ver); \ psTracePrintProtocolVersionNew(0, \ - IS_SERVER(ssl) ? "Server activated" : "Client activated", \ + MATRIX_IS_SERVER(ssl) ? "Server activated" : "Client activated", \ (ssl)->activeVersion, \ PS_TRUE); \ } \ @@ -319,7 +171,7 @@ psProtocolVersion_t psFlagToVer(int32_t flag); { \ ((ssl)->activeVersion = ((ver) | v_tls_negotiated)); \ psTracePrintProtocolVersionNew(0, \ - IS_SERVER(ssl) ? "Server negotiated" : "Client negotiated", \ + MATRIX_IS_SERVER(ssl) ? "Server negotiated" : "Client negotiated", \ (ssl)->activeVersion, \ PS_TRUE); \ } \ @@ -329,7 +181,7 @@ psProtocolVersion_t psFlagToVer(int32_t flag); { \ ((ssl)->activeVersion = ((ssl)->activeVersion & ~v_tls_negotiated)); \ psTracePrintProtocolVersionNew(0, \ - IS_SERVER(ssl) ? "Server unnegotiated" : "Client unnegotiated", \ + MATRIX_IS_SERVER(ssl) ? "Server unnegotiated" : "Client unnegotiated", \ (ssl)->activeVersion, \ PS_TRUE); \ } \ @@ -338,7 +190,7 @@ psProtocolVersion_t psFlagToVer(int32_t flag); do \ { \ psTracePrintProtocolVersionNew(0, \ - IS_SERVER(ssl) ? "Server deactivated" : "Client deactivated", \ + MATRIX_IS_SERVER(ssl) ? "Server deactivated" : "Client deactivated", \ (ssl)->activeVersion, \ PS_TRUE); \ (ssl)->activeVersion = v_undefined; \ diff --git a/matrixssl/prf.c b/matrixssl/prf.c index c1d5f92..12ebfda 100644 --- a/matrixssl/prf.c +++ b/matrixssl/prf.c @@ -36,6 +36,10 @@ #if defined(USE_TLS_PRF) || defined(USE_TLS_PRF2) +# ifndef DEBUG_PRF +/* # define DEBUG_PRF */ /* Enable PRF input/output hex dumping. */ +# endif + # ifdef USE_TLS_PRF int32_t prf(const unsigned char *sec, psSize_t secLen, const unsigned char *seed, psSize_t seedLen, @@ -368,6 +372,7 @@ L_RETURN: return rc; } +# ifndef USE_ROT_TLS12_PRF /******************************************************************************/ /* Psuedo-random function. TLS uses this for key generation and hashing @@ -380,6 +385,11 @@ int32_t prf2(const unsigned char *sec, psSize_t secLen, int32_t rc; uint16_t i; +# ifdef DEBUG_PRF + psTraceBytes("prf2 sec", sec, secLen); + psTraceBytes("prf2 seed", seed, seedLen); +# endif + psAssert(outLen <= SSL_MAX_KEY_BLOCK_SIZE); if ((rc = pSha2(sec, secLen, seed, seedLen, sha2out, outLen, flags)) < 0) @@ -393,8 +403,15 @@ int32_t prf2(const unsigned char *sec, psSize_t secLen, out[i] = sha2out[i]; } memzero_s(sha2out, SSL_MAX_KEY_BLOCK_SIZE); + +# ifdef DEBUG_PRF + psTraceBytes("prf2 out", out, outLen); +# endif + return outLen; } +# endif /* !USE_ROT_TLS12_PRF */ + # endif /* USE_TLS_1_2 */ # ifdef USE_EAP_FAST diff --git a/matrixssl/sslDecode.c b/matrixssl/sslDecode.c index 578a13f..08c0c5a 100644 --- a/matrixssl/sslDecode.c +++ b/matrixssl/sslDecode.c @@ -150,6 +150,17 @@ psRes_t validateRecordHdrVersion(ssl_t *ssl) } # endif +# ifdef USE_LENIENT_TLS_RECORD_VERSION_MATCHING + /* If using TLS, allow the record header to have any TLS version + for compatility. There have been e.g. some real world servers + that always encode TLS 1.1 in the record header, even after + TLS 1.2 has been chosen or negotiated. */ + if (NGTD_VER(ssl, v_tls_any) && (recordVer & v_tls_any)) + { + ok = PS_TRUE; + } +# endif + if (ok) { return MATRIXSSL_SUCCESS; @@ -183,7 +194,6 @@ out_fail: "Unexpected version", recordVer, PS_TRUE); - ssl->err = SSL_ALERT_PROTOCOL_VERSION; return MATRIXSSL_ERROR; } @@ -363,7 +373,7 @@ int32 matrixSslDecode(ssl_t *ssl, unsigned char **buf, uint32 *len, *error = PS_SUCCESS; if (ssl->flags & SSL_FLAGS_ERROR || ssl->flags & SSL_FLAGS_CLOSED) { - psTraceInfo("Can't use matrixSslDecode on closed/error-flagged sess\n"); + psTraceErrr("Can't use matrixSslDecode on closed/error-flagged sess\n"); *error = PS_PROTOCOL_FAIL; return MATRIXSSL_ERROR; } @@ -389,7 +399,7 @@ int32 matrixSslDecode(ssl_t *ssl, unsigned char **buf, uint32 *len, } psAssert(rc == SSL_NO_TLS_1_3); - if (IS_CLIENT(ssl)) + if (MATRIX_IS_CLIENT(ssl)) { /* Check for possibility to fail early on an unsupported downgrade. @@ -693,8 +703,9 @@ SKIP_RECORD_PARSE: real mess trying to keep the expectedEpoch up-to-date when we can't possibly know how many epoch increments the peer has made before we receive a FINISHED message or an APPLICATION DATA record */ - if (rc == 1 && ssl->rec.type == SSL_RECORD_TYPE_HANDSHAKE && - ssl->hsState == SSL_HS_FINISHED) + if (rc == 1 + && ssl->rec.type == SSL_RECORD_TYPE_HANDSHAKE + && ssl->hsState == SSL_HS_FINISHED) { /* Special handlers for these CCS/Finished cases because epoch could be larger for a good reason */ @@ -720,7 +731,9 @@ SKIP_RECORD_PARSE: else if (rc != 0) { psTraceIntDtls("Epoch mismatch %d ", ssl->rec.epoch[1]); - psTraceIntDtls("on a record type of %d\n", ssl->rec.type); + psTraceIntDtls("expected %d ", ssl->expectedEpoch[1]); + psTraceIntDtls("on a record type of %d", ssl->rec.type); + psTraceIntDtls("at state %d\n", ssl->hsState); /* Another corner case where the peer has sent repeat FINISHED messages when we are in the state where we are finished. @@ -1113,38 +1126,38 @@ ADVANCE_TO_APP_DATA: { # ifdef USE_SHA256 case SHA256_HASH_SIZE: - psSha256PreInit(&md.sha256); - psSha256Init(&md.sha256); + psSha256PreInit(&md.u.sha256); + psSha256Init(&md.u.sha256); while (rc > 0) { - psSha256Update(&md.sha256, tmp, 64); + psSha256Update(&md.u.sha256, tmp, 64); rc--; } - psSha256Final(&md.sha256, tmp); + psSha256Final(&md.u.sha256, tmp); break; # endif # ifdef USE_SHA384 case SHA384_HASH_SIZE: - psSha384PreInit(&md.sha384); - psSha384Init(&md.sha384); + psSha384PreInit(&md.u.sha384); + psSha384Init(&md.u.sha384); while (rc > 0) { - psSha384Update(&md.sha384, tmp, 128); + psSha384Update(&md.u.sha384, tmp, 128); rc--; } - psSha384Final(&md.sha384, tmp); + psSha384Final(&md.u.sha384, tmp); break; # endif # ifdef USE_SHA1 case SHA1_HASH_SIZE: - psSha1PreInit(&md.sha1); - psSha1Init(&md.sha1); + psSha1PreInit(&md.u.sha1); + psSha1Init(&md.u.sha1); while (rc > 0) { - psSha1Update(&md.sha1, tmp, 64); + psSha1Update(&md.u.sha1, tmp, 64); rc--; } - psSha1Final(&md.sha1, tmp); + psSha1Final(&md.u.sha1, tmp); break; # endif default: @@ -1923,8 +1936,18 @@ encodeResponse: session is made on that side, so always send the current session Re-send the backed up user extensions (if any). TODO: test this. */ - rc = matrixSslEncodeClientHello(ssl, &tmpout, 0, 0, requiredLen, - ssl->userExt, &options); + rc = matrixSslEncodeClientHello(ssl, + &tmpout, +# ifdef ENABLE_SECURE_REHANDSHAKES + ssl->tlsClientCipherSuites, + ssl->tlsClientCipherSuitesLen, +# else + 0, + 0, +# endif + requiredLen, + ssl->userExt, + &options); } else { @@ -2456,8 +2479,7 @@ hsStateDetermined: */ if (ssl->hsState == SSL_HS_FINISHED) { - if (sslSnapshotHSHash(ssl, hsMsgHash, - (ssl->flags & SSL_FLAGS_SERVER) ? 0 : SSL_FLAGS_SERVER) <= 0) + if (sslSnapshotHSHash(ssl, hsMsgHash, PS_FALSE, PS_TRUE) <= 0) { psTraceErrr("Error snapshotting HS hash\n"); ssl->err = SSL_ALERT_INTERNAL_ERROR; @@ -2469,7 +2491,7 @@ hsStateDetermined: { /* Same issue as above for client auth. Need a handshake snapshot that doesn't include this message we are about to process */ - if (sslSnapshotHSHash(ssl, hsMsgHash, -1) <= 0) + if (sslSnapshotHSHash(ssl, hsMsgHash, PS_FALSE, PS_FALSE) <= 0) { psTraceErrr("Error snapshotting HS hash\n"); ssl->err = SSL_ALERT_INTERNAL_ERROR; @@ -2819,6 +2841,19 @@ SKIP_HSHEADER_PARSE: feature for the re-handshake. */ ssl->extClientCertKeyStateFlags = EXT_CLIENT_CERT_KEY_STATE_INIT; # endif /* USE_EXT_CLIENT_CERT_KEY_LOADING */ + +#ifdef USE_DTLS + if (ACTV_VER(ssl, v_dtls_any)) + { + /* Server initiated rehandshake - brign resend epoch up to + date ... shouldn't this be done when entering + done-state? */ + ssl->resendEpoch[0] = ssl->epoch[0]; + ssl->resendEpoch[1] = ssl->epoch[1]; + ssl->appDataExch = 0; + ssl->msn = ssl->resendMsn = 0; + } +#endif break; /******************************************************************************/ diff --git a/matrixssl/sslEncode.c b/matrixssl/sslEncode.c index 2b63af5..c3b7690 100644 --- a/matrixssl/sslEncode.c +++ b/matrixssl/sslEncode.c @@ -5,7 +5,7 @@ * Secure Sockets Layer protocol message encoding portion of MatrixSSL. */ /* - * Copyright (c) 2013-2018 INSIDE Secure Corporation + * Copyright (c) 2013-2019 INSIDE Secure Corporation * Copyright (c) PeerSec Networks, 2002-2011 * All Rights Reserved * @@ -34,6 +34,10 @@ #include "matrixsslImpl.h" +#ifdef USE_ROT_CRYPTO +# include "../crypto-rot/rotCommon.h" +#endif + /******************************************************************************/ # ifdef USE_IDENTITY_CERTIFICATES @@ -149,7 +153,7 @@ int32 matrixSslEncode(ssl_t *ssl, unsigned char *buf, uint32 size, if (ssl->flags & SSL_FLAGS_ERROR || ssl->hsState != SSL_HS_DONE || ssl->flags & SSL_FLAGS_CLOSED) { - psTraceInfo("Bad SSL state for matrixSslEncode call attempt: "); + psTraceErrr("Bad SSL state for matrixSslEncode call attempt: "); psTracePrintSslFlags(ssl->flags); psTracePrintHsState(ssl->hsState, PS_TRUE); return MATRIXSSL_ERROR; @@ -529,7 +533,7 @@ int accountForEcdsaSizeChange(ssl_t *ssl, and 3 byte offset */ if (Memcmp(msgLenLoc, msgLenLoc + 8, 3) != 0) { - psTraceInfo("ERROR: ECDSA SKE DTLS fragmentation unsupported\n"); + psTraceErrr("ERROR: ECDSA SKE DTLS fragmentation unsupported\n"); return MATRIXSSL_ERROR; } } @@ -638,6 +642,12 @@ psResSize_t calcCkeSize(ssl_t *ssl) # ifdef USE_ECC_CIPHER_SUITE if ((ssl->flags & SSL_FLAGS_ECC_CIPHER) != 0) { +# ifdef USE_X25519 + if (ssl->sec.peerCurveId == namedgroup_x25519) + { + return PS_DH_X25519_PUBLIC_KEY_BYTES + 1; + } +# endif return (ssl->sec.eccKeyPriv->curve->size * 2) + 2; } # endif /* USE_ECC_CIPHER_SUITE */ @@ -746,6 +756,20 @@ static int32 nowDoCkePka(ssl_t *ssl) psAssert(pka->outbuf == ssl->sec.premaster); if (pka->type == PKA_AFTER_ECDH_SECRET_GEN) { +# ifdef USE_X25519 + if (ssl->sec.peerCurveId == namedgroup_x25519) + { + rc = psDhX25519GenSharedSecret(ssl->sec.x25519KeyPub, + ssl->sec.x25519KeyPriv.priv, + ssl->sec.premaster); + if (rc < 0) + { + return rc; + } + ssl->sec.premasterSize = PS_DH_X25519_SHARED_SECRET_BYTES; + goto gen_premaster_done; + } +# endif if ((rc = psEccGenSharedSecret(ssl->sec.eccDhKeyPool, ssl->sec.eccKeyPriv, ssl->sec.eccKeyPub, ssl->sec.premaster, &ssl->sec.premasterSize, @@ -1045,7 +1069,7 @@ if (g_reusePreLen == 0) # endif /* USE_DTLS */ clearPkaAfter(ssl); # else /* RSA is the 'default' so if that didn't get hit there is a problem */ - psTraceInfo("There is no handler for writeClientKeyExchange. ERROR\n"); + psTraceErrr("There is no handler for writeClientKeyExchange. ERROR\n"); return MATRIXSSL_ERROR; # endif /* USE_RSA_CIPHER_SUITE */ @@ -1058,6 +1082,10 @@ if (g_reusePreLen == 0) } # endif /* USE_DHE_CIPHER_SUITE */ +# ifdef USE_X25519 +gen_premaster_done: +# endif + /* Now that we've got the premaster secret, derive the various symmetric keys using it and the client and server random values. @@ -1319,7 +1347,7 @@ ok: certReqLen += 1; /* Add on ECDSA_SIGN support */ # endif /* USE_ECC */ # else - psTraceInfo("No server CAs loaded for client authentication\n"); + psTraceErrr("No server CAs loaded for client authentication\n"); return MATRIXSSL_ERROR; # endif } @@ -2410,6 +2438,8 @@ resumeFlightEncryption: rc = nowDoCkePka(ssl); if (rc < 0) { + psTraceErrr("nowDoCkePka failed\n"); + psTraceIntInfo("nowDoCkePka returned: %d\n", rc); return rc; } } @@ -2452,8 +2482,8 @@ int32_t processFinished(ssl_t *ssl, flightEncode_t *msg) { if (msg->hsMsg == SSL_HS_FINISHED) { - /* Epoch is incremented and the sequence numbers are reset for - this message */ + /* Epoch is incremented and the sequence numbers are reset for + this message */ incrTwoByte(ssl, ssl->epoch, 1); zeroSixByte(ssl->rsn); } @@ -2483,7 +2513,7 @@ int32_t processFinished(ssl_t *ssl, flightEncode_t *msg) activate the write cipher */ if ((rc = sslActivateWriteCipher(ssl)) < 0) { - psTraceInfo("Error Activating Write Cipher\n"); + psTraceErrr("Error Activating Write Cipher\n"); clearFlightList(ssl); return rc; } @@ -2492,8 +2522,10 @@ int32_t processFinished(ssl_t *ssl, flightEncode_t *msg) hash because those updates are done in the encryptRecord call below for each message. THAT was done because of a possible delay in a PKA op */ - rc = sslSnapshotHSHash(ssl, ssl->delayHsHash, - ssl->flags & SSL_FLAGS_SERVER); + rc = sslSnapshotHSHash(ssl, + ssl->delayHsHash, + PS_TRUE, + PS_TRUE); if (rc <= 0) { psTraceErrr("Error snapshotting HS hash flight\n"); @@ -2536,13 +2568,14 @@ static int32 encryptFlight(ssl_t *ssl, unsigned char **end) /* NEGATIVE ECDSA - save the end of the flight buffer */ origEnd = *end; + (void)origEnd; /* Unused on some code paths. */ + # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING if (!ssl->extCvSigOpPending) { ssl->extCvOrigFlightEnd = origEnd; } # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ - /* PS_VARIABLE_SET_BUT_UNUSED(origEnd); */ msg = ssl->flightEncode; while (msg) @@ -3134,7 +3167,7 @@ static int32 encryptCompressedRecord(ssl_t *ssl, int32 type, int32 messageSize, Memset(ssl->zlibBuffer, 0, ptLen + MAX_ZLIB_COMPRESSED_OH); if (ssl->zlibBuffer == NULL) { - psTraceInfo("Error allocating compression buffer\n"); + psTraceErrr("Error allocating compression buffer\n"); return MATRIXSSL_ERROR; } dataToMacAndEncrypt = ssl->zlibBuffer; @@ -4255,7 +4288,7 @@ static int32 writeNewSessionTicket(ssl_t *ssl, sslBuf_t *out) rc = (int32) (end - c); if (matrixCreateSessionTicket(ssl, c, &rc) < 0) { - psTraceInfo("Error generating session ticket\n"); + psTraceErrr("Error generating session ticket\n"); return MATRIXSSL_ERROR; } c += rc; @@ -4290,7 +4323,6 @@ static int32 writeServerKeyExchange(ssl_t *ssl, sslBuf_t *out, uint32 pLen, # ifndef USE_ONLY_PSK_CIPHER_SUITE unsigned char *tbsStart; sslIdentity_t *chosen = ssl->chosenIdentity; - int32_t skeSigAlg; # endif # if defined(USE_PSK_CIPHER_SUITE) && defined(USE_ANON_DH_CIPHER_SUITE) @@ -4508,9 +4540,12 @@ static int32 writeServerKeyExchange(ssl_t *ssl, sslBuf_t *out, uint32 pLen, } # endif /* USE_ECC_CIPHER_SUITE */ -# ifndef USE_ONLY_PSK_CIPHERSUITE +# ifndef USE_ONLY_PSK_CIPHER_SUITE if (ssl->flags & (SSL_FLAGS_DHE_WITH_RSA | SSL_FLAGS_DHE_WITH_DSA)) { + int32_t skeSigAlg; + psBool_t needPreHash = PS_TRUE; + /* Message length been pre-computed, and we have written the public value and/or the PSK hint. Next we shall choose the signature algorithm, write the signature algorithm identifier (if (D)TLS 1.2) @@ -4523,19 +4558,24 @@ static int32 writeServerKeyExchange(ssl_t *ssl, sslBuf_t *out, uint32 pLen, return skeSigAlg; } +# ifdef USE_ROT_ECC + needPreHash = PS_FALSE; +# endif + /* 2. Compute the hash. */ /* 3. Setup pkaAfter_t for delayed signing op. */ rc = tlsPrepareSkeSignature(ssl, skeSigAlg, tbsStart, - c); + c, + needPreHash); if (rc < 0) { return rc; } c += rc; } -# endif /* USE_ONLY_PSK_CIPHERSUITE */ +# endif /* USE_ONLY_PSK_CIPHER_SUITE */ rc = postponeEncryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, @@ -4571,12 +4611,12 @@ int32 matrixSslEncodeHelloRequest(ssl_t *ssl, sslBuf_t *out, if (ssl->flags & SSL_FLAGS_ERROR || ssl->flags & SSL_FLAGS_CLOSED) { - psTraceInfo("SSL flag error in matrixSslEncodeHelloRequest\n"); + psTraceErrr("SSL flag error in matrixSslEncodeHelloRequest\n"); return MATRIXSSL_ERROR; } if (!(ssl->flags & SSL_FLAGS_SERVER) || (ssl->hsState != SSL_HS_DONE)) { - psTraceInfo("SSL state error in matrixSslEncodeHelloRequest\n"); + psTraceErrr("SSL state error in matrixSslEncodeHelloRequest\n"); return MATRIXSSL_ERROR; } @@ -5187,7 +5227,9 @@ static int32 writeFinished(ssl_t *ssl, sslBuf_t *out) /* Output the hash of messages we've been collecting so far into the buffer */ - c += postponeSnapshotHSHash(ssl, c, ssl->flags & SSL_FLAGS_SERVER); + c += postponeSnapshotHSHash(ssl, + c, + ssl->flags & SSL_FLAGS_SERVER); rc = postponeEncryptRecord(ssl, SSL_RECORD_TYPE_HANDSHAKE, @@ -5373,7 +5415,10 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, psSize_t messageSize, cipherLen, cookieLen, addRenegotiationScsv; tlsExtension_t *ext; uint32 extLen; - short i, useTicket; +# ifdef USE_STATELESS_SESSION_TICKETS + short useTicket; +#endif + short i; # ifdef USE_TLS_1_2 psSize_t sigHashLen, sigHashFlags; /* 2b len + 2b * MAX sig hash combos */ @@ -5401,14 +5446,14 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, } if (ssl->flags & SSL_FLAGS_ERROR || ssl->flags & SSL_FLAGS_CLOSED) { - psTraceInfo("SSL flag error in matrixSslEncodeClientHello\n"); + psTraceErrr("SSL flag error in matrixSslEncodeClientHello\n"); return MATRIXSSL_ERROR; } if (ssl->flags & SSL_FLAGS_SERVER || (ssl->hsState != SSL_HS_SERVER_HELLO && ssl->hsState != SSL_HS_DONE && ssl->hsState != SSL_HS_HELLO_REQUEST )) { - psTraceInfo("SSL state error in matrixSslEncodeClientHello\n"); + psTraceErrr("SSL state error in matrixSslEncodeClientHello\n"); return MATRIXSSL_ERROR; } @@ -5446,7 +5491,7 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, { if ((cipherLen = sslGetCipherSpecListLen(ssl)) == 2) { - psTraceInfo("No cipher suites enabled (or no key material)\n"); + psTraceErrr("No cipher suites enabled (or no key material)\n"); return MATRIXSSL_ERROR; } } @@ -5478,6 +5523,18 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, { cipherLen += 2; /* signalling cipher id 0x00FF */ addRenegotiationScsv = 1; + if (cipherSpecLen > 0) + { + /* Store the initial ClientHello cipherlist for re-sending during + possible server-initiated renegotiations. */ + ssl->tlsClientCipherSuites = psMalloc(ssl->hsPool, + 2*cipherSpecLen); + for (i = 0; i < cipherSpecLen; i++) + { + ssl->tlsClientCipherSuites[i] = cipherSpecs[i]; + } + ssl->tlsClientCipherSuitesLen = cipherSpecLen; + } } # endif if (options->fallbackScsv) @@ -5487,7 +5544,7 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, /** If a client sets ClientHello.client_version to its highest supported protocol version, it MUST NOT include TLS_FALLBACK_SCSV. @see https://tools.ietf.org/html/rfc7507#section-4 */ - psTraceInfo("Cannot set fallbackScsv if using maximum supported TLS version.\n"); + psTraceErrr("Cannot set fallbackScsv if using maximum supported TLS version.\n"); return MATRIXSSL_ERROR; } if (ssl->sessionIdLen > 0) @@ -5496,7 +5553,7 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, to the protocol version negotiated for that session, it MUST NOT include TLS_FALLBACK_SCSV. @see https://tools.ietf.org/html/rfc7507#section-4 */ - psTraceInfo("Cannot set fallbackScsv if attempting to resume a connection.\n"); + psTraceErrr("Cannot set fallbackScsv if attempting to resume a connection.\n"); return MATRIXSSL_ERROR; } cipherLen += 2; /* signalling cipher id 0x5600 */ @@ -5548,7 +5605,7 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, } else { - psTraceInfo("Unsupported maxFragLen value to session options\n"); + psTraceErrr("Unsupported maxFragLen value to session options\n"); return PS_ARG_FAIL; } } @@ -5633,8 +5690,8 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, } # endif /* USE_ECC_CIPHER_SUITE */ - useTicket = 0; # ifdef USE_STATELESS_SESSION_TICKETS + useTicket = 0; if (options && options->ticketResumption == 1) { useTicket = 1; @@ -6064,6 +6121,12 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, if (curveListLen > 0) { psTracePrintExtensionCreate(ssl, EXT_ELLIPTIC_CURVE); + psTracePrintTls13NamedGroupList(INDENT_EXTENSION, + "elliptic curves", + eccCurveList, + curveListLen, + ssl, + PS_TRUE); ssl->extFlags.req_elliptic_curve = 1; *c = (EXT_ELLIPTIC_CURVE & 0xFF00) >> 8; c++; *c = EXT_ELLIPTIC_CURVE & 0xFF; c++; @@ -6095,6 +6158,11 @@ int32_t matrixSslEncodeClientHello(ssl_t *ssl, sslBuf_t *out, *c = sigHashLen & 0xFF; c++; Memcpy(c, sigHash, sigHashLen); c += sigHashLen; + psTracePrintTls13SigAlgListBigEndian(INDENT_EXTENSION, + "signature_algorithms", + (const uint16_t*)(sigHash + 2), + sigHashLen > 2 ? (sigHashLen - 2)/2 : 0, + PS_TRUE); # endif # ifdef USE_STATELESS_SESSION_TICKETS @@ -6314,7 +6382,18 @@ static int32 writeClientKeyExchange(ssl_t *ssl, sslBuf_t *out) # ifdef USE_ECC_CIPHER_SUITE if (ssl->flags & SSL_FLAGS_ECC_CIPHER) { +# ifdef USE_X25519 + if (ssl->sec.peerCurveId == namedgroup_x25519) + { + keyLen = PS_DH_X25519_PUBLIC_KEY_BYTES + 1; + } + else + { +# endif keyLen = (ssl->sec.eccKeyPriv->curve->size * 2) + 2; +# ifdef USE_X25519 + } +# endif } else { @@ -6487,6 +6566,15 @@ static int32 writeClientKeyExchange(ssl_t *ssl, sslBuf_t *out) { keyLen--; *c = keyLen & 0xFF; c++; +# ifdef USE_X25519 + if (ssl->sec.peerCurveId == namedgroup_x25519) + { + Memcpy(c, + ssl->sec.x25519KeyPriv.pub, + PS_DH_X25519_PUBLIC_KEY_BYTES); + goto export_done; + } +# endif /* USE_X25519 */ if (psEccX963ExportKey(ssl->hsPool, ssl->sec.eccKeyPriv, c, &keyLen) < 0) { @@ -6507,12 +6595,25 @@ static int32 writeClientKeyExchange(ssl_t *ssl, sslBuf_t *out) } Memcpy(ssl->ckeMsg, c - 1, ssl->ckeSize); } +# endif +# ifdef USE_X25519 + export_done: # endif c += keyLen; /* Generate premaster and free ECC key material */ +# ifdef USE_X25519 + if (ssl->sec.peerCurveId == namedgroup_x25519) + { + ssl->sec.premasterSize = PS_DH_X25519_SHARED_SECRET_BYTES; + goto alloc_premaster; + } +# endif /* USE_X25519 */ ssl->sec.premasterSize = ssl->sec.eccKeyPriv->curve->size; +# ifdef USE_X25519 + alloc_premaster: +# endif ssl->sec.premaster = psMalloc(ssl->hsPool, ssl->sec.premasterSize); if (ssl->sec.premaster == NULL) { @@ -6705,7 +6806,7 @@ static int32 writeClientKeyExchange(ssl_t *ssl, sslBuf_t *out) c += keyLen; # else /* RSA is the 'default' so if that didn't get hit there is a problem */ - psTraceInfo("There is no handler for writeClientKeyExchange. ERROR\n"); + psTraceErrr("There is no handler for writeClientKeyExchange. ERROR\n"); return MATRIXSSL_ERROR; # endif /* USE_RSA_CIPHER_SUITE */ # endif /* !USE_ONLY_PSK_CIPHER_SUITE */ @@ -6775,7 +6876,7 @@ static int32_t handleAsyncCvSigOp(ssl_t *ssl, pkaAfter_t *pka, unsigned char *ha ssl->extCvSigAlg = PS_ECC; } - if (NGTD_VER(ssl, v_tls_with_signature_algorithmts) + if (NGTD_VER(ssl, v_tls_with_signature_algorithms) || ssl->extCvSigAlg == PS_RSA) { hash_tbs = hash; @@ -6845,18 +6946,25 @@ static int32_t handleAsyncCvSigOp(ssl_t *ssl, pkaAfter_t *pka, unsigned char *ha } # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ +# ifndef USE_BUFFERED_HS_HASH static int32 getSnapshotHSHash(ssl_t *ssl, unsigned char msgHash[SHA512_HASH_SIZE], pkaAfter_t *pka) { - /* Does a smart default hash automatically for us */ - if (sslSnapshotHSHash(ssl, msgHash, -1) <= 0) + int32_t rc; + + rc = sslSnapshotHSHash(ssl, + msgHash, + PS_TRUE, + PS_FALSE); + if (rc <= 0) { - psTraceInfo("Internal error: handshake hash failed\n"); + psTraceErrr("Internal error: handshake hash failed\n"); return MATRIXSSL_ERROR; } + + # ifdef USE_TLS_1_2 - /* Tweak if needed */ if (NGTD_VER(ssl, v_tls_with_signature_algorithms)) { switch (pka->inlen) @@ -6884,24 +6992,28 @@ static int32 getSnapshotHSHash(ssl_t *ssl, return PS_SUCCESS; } +# endif /* USE_BUFFERED_HS_HASH */ # ifdef USE_ECC static int nowDoCvPkaInnerECDSA(ssl_t *ssl, pkaAfter_t *pka, unsigned char msgHash[SHA512_HASH_SIZE], psBuf_t *out) { - psPool_t *pkiPool = NULL; - int32_t rc = PS_SUCCESS; - unsigned char *tmpEcdsa; + unsigned char *tmpEcdsa = NULL; psSize_t len, hashTbsLen; unsigned char *hashTbs; sslIdentity_t *chosen = ssl->chosenIdentity; + unsigned char *sig; + psSize_t sigLen; + int32_t sigAlg; if (chosen == NULL) { return PS_UNSUPPORTED_FAIL; } + sigAlg = OID_ECDSA_TLS_SIG_ALG; + # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING if (ssl->extCvSigOpInUse) { @@ -6929,12 +7041,6 @@ static int nowDoCvPkaInnerECDSA(ssl_t *ssl, pkaAfter_t *pka, */ # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ - /* Only need to allocate 1 larger because 1 has already been added */ - if ((tmpEcdsa = psMalloc(ssl->hsPool, pka->user + 1)) == NULL) - { - return PS_MEM_FAIL; - } - # ifdef USE_TLS_1_2 if (NGTD_VER(ssl, v_tls_with_signature_algorithms)) { @@ -6943,6 +7049,13 @@ static int nowDoCvPkaInnerECDSA(ssl_t *ssl, pkaAfter_t *pka, */ hashTbs = msgHash; hashTbsLen = pka->inlen; +# ifdef USE_ROT_ECC + /* With RoT, we need to provide the whole transcript to the signing + function. Hashing will be performed within RoT. */ + hashTbs = ssl->hsMsgBuf.start; + hashTbsLen = ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start; + sigAlg = psRotCurveToSigAlg(chosen->privKey.key.ecc.curve->curveId); +# endif /* USE_ROT_ECC */ } else { @@ -6977,12 +7090,35 @@ static int nowDoCvPkaInnerECDSA(ssl_t *ssl, pkaAfter_t *pka, Length of outbuf is increased by 1. */ len = pka->user + 1; - rc = psEccDsaSign(pkiPool, &chosen->privKey.key.ecc, - hashTbs, hashTbsLen, tmpEcdsa, &len, 1, pka->data); + +# ifdef USE_ROT_ECC + psAssert(hashTbs == ssl->hsMsgBuf.start && + hashTbsLen == ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start); +# endif + rc = psSign( + NULL, + &chosen->privKey, + sigAlg, + hashTbs, + hashTbsLen, + &sig, + &sigLen, + NULL); if (rc != PS_SUCCESS) { goto out; } + tmpEcdsa = psMalloc(ssl->hsPool, len); + if (tmpEcdsa == NULL) + { + return PS_MEM_FAIL; + } + tmpEcdsa[0] = (sigLen << 8) & 0xff00; + tmpEcdsa[1] = sigLen & 0xff; + Memcpy(&tmpEcdsa[2], sig, sigLen); + len = sigLen + 2; + psFree(sig, ssl->hsPool); + # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING } /* closing brace for: if (ssl->extCvSigOpInUse) { ... } else { */ # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ @@ -7062,7 +7198,6 @@ static int nowDoCvPkaInnerECDSA(ssl_t *ssl, pkaAfter_t *pka, # endif /* USE_DTLS */ out: - # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING if (ssl->extCvSigOpInUse) { @@ -7090,7 +7225,10 @@ static int nowDoCvPkaInnerRSA(ssl_t *ssl, pkaAfter_t *pka, psPool_t *pkiPool = NULL; sslIdentity_t *chosen = ssl->chosenIdentity; int32_t rc; - int32_t using_tls_1_2; + int32_t sigAlg; + psSignOpts_t opts; + unsigned char *tbs, *sigBuf; + psSize_t tbsLen, sigLen; if (chosen == NULL) { @@ -7116,64 +7254,46 @@ static int nowDoCvPkaInnerRSA(ssl_t *ssl, pkaAfter_t *pka, { # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ + /* TLS 1.2 uses PKCS #1.5 RSA sigs. TLS 1.1 and below do not. */ + sigAlg = OID_RSA_TLS_SIG_ALG; /* Override if using TLS 1.2. */ + # ifdef USE_TLS_1_2 if (NGTD_VER(ssl, v_tls_with_signature_algorithms)) { - /* RFC: "The hash and signature algorithms used in the - signature MUST be one of those present in the - supported_signature_algorithms field of the - CertificateRequest message. In addition, the hash and - signature algorithms MUST be compatible with the key in the - client's end-entity certificate. - - We've done the above tests in the parse of the - CertificateRequest message and wouldn't be here if our - certs didn't match the sigAlgs. However, we do have - to test for both sig algorithm types here to find the - hash strength because the sig alg might not match the - pubkey alg. This was also already confirmed in - CertRequest parse so wouldn't be here if not allowed */ - using_tls_1_2 = 1; /* TLS 1.2 defined and used. */ + sigAlg = OID_RSA_PKCS15_SIG_ALG; } - else +# endif /* USE_TLS_1_2 */ + + tbs = msgHash; + tbsLen = pka->inlen; +# ifdef USE_ROT_ECC + /* crypto-rot wants the raw handshake_messages instead of a hash. */ + tbs = ssl->hsMsgBuf.start; + tbsLen = ssl->hsMsgBuf.buf - ssl->hsMsgBuf.start; +# endif + + Memset(&opts, 0, sizeof(opts)); + + opts.flags |= PS_SIGN_OPTS_USE_PREALLOCATED_OUTBUF; + opts.userData = pka->data; + + sigBuf = pka->outbuf; + + rc = psSign(pkiPool, + &chosen->privKey, + sigAlg, + tbs, + tbsLen, + &sigBuf, + &sigLen, + &opts); + if (rc < 0) { - using_tls_1_2 = 0; /* TLS 1.2 defined but not used. */ + rc = MATRIXSSL_ERROR; + goto out; } -# else /* ! USE_TLS_1_2 */ - using_tls_1_2 = 0; /* TLS 1.2 not defined and thus not used. */ -# endif /* USE_TLS_1_2 */ - - psAssert(using_tls_1_2 == 0 || using_tls_1_2 == 1); - -# ifdef USE_TLS_1_2 - /* - In TLS 1.2, the RSASSA-PKCS1-v1_5 signature scheme must - be used. In this scheme, the signed element is not the raw hash - but a DER-encoded DigestInfo struct. Only privRsaEncryptSignedElement - can handle this case. - */ - if (using_tls_1_2) - { - rc = privRsaEncryptSignedElement(pkiPool, &chosen->privKey.key.rsa, - msgHash, pka->inlen, pka->outbuf, - chosen->privKey.keysize, pka->data); - } -# endif /* USE_TLS_1_2 */ - - if (!using_tls_1_2) - { - rc = psRsaEncryptPriv(pkiPool, &chosen->privKey.key.rsa, msgHash, - pka->inlen, pka->outbuf, chosen->privKey.keysize, - pka->data); - } - - if (rc < 0) - { - rc = MATRIXSSL_ERROR; - goto out; - } # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING -} /* Closing brace for: if (ssl->extCvSigOpInUse) { } ... else { .. */ + } /* Closing brace for: if (ssl->extCvSigOpInUse) { } ... else { .. */ # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ # ifdef USE_DTLS @@ -7210,7 +7330,7 @@ static int32 nowDoCvPka(ssl_t *ssl, psBuf_t *out) { pkaAfter_t *pka; unsigned char msgHash[SHA512_HASH_SIZE]; - int32_t rc; + int32_t rc = PS_FAILURE; pka = &ssl->pkaAfter[0]; @@ -7229,11 +7349,15 @@ static int32 nowDoCvPka(ssl_t *ssl, psBuf_t *out) /* Compute the handshake_messages hash. + crypto-rot needs the raw handshake_messages instead of a hash. + Fetch the raw handshake_messages later in the Inner function. */ +# ifndef USE_BUFFERED_HS_HASH if (getSnapshotHSHash(ssl, msgHash, pka) < 0) { return MATRIXSSL_ERROR; } +# endif /* Sign it. @@ -7251,21 +7375,21 @@ static int32 nowDoCvPka(ssl_t *ssl, psBuf_t *out) rc = nowDoCvPkaInnerRSA(ssl, pka, msgHash, out); break; default: - psTraceInfo("Unsupported algorithm type in nowDoCvPka\n"); + psTraceErrr("Unsupported algorithm type in nowDoCvPka\n"); return MATRIXSSL_ERROR; # endif /* USE_RSA */ } # if !defined(USE_ECC) && !defined(USE_RSA) - psTraceInfo("Error: no algorithm support for CertificateVerify signature\n"); + psTraceErrr("Error: no algorithm support for CertificateVerify signature\n"); return MATRIXSSL_ERROR; # endif /* !USE_ECC && !USE_RSA */ if (rc < 0) { return rc; /* PS_PENDING or error. */ - } + return PS_SUCCESS; } @@ -7299,7 +7423,7 @@ static int32 writeCertificateVerify(ssl_t *ssl, sslBuf_t *out) if ((pkaAfter = getPkaAfterCv(ssl)) == NULL) { - psTraceInfo("getPkaAfter error for certVerify\n"); + psTraceErrr("getPkaAfter error for certVerify\n"); return MATRIXSSL_ERROR; } @@ -7387,7 +7511,7 @@ static int32 writeCertificateVerify(ssl_t *ssl, sslBuf_t *out) ssl->serverSigAlgs); if (sigAlg <= 0) { - psTraceInfo("Need more hash support for certVerify\n"); + psTraceErrr("Need more hash support for certVerify\n"); return MATRIXSSL_ERROR; } } @@ -7467,7 +7591,7 @@ static int32 writeCertificateVerify(ssl_t *ssl, sslBuf_t *out) if (getSignatureAndHashAlgorithmEncoding(sigAlg, &b1, &b2, &hashSize) < 0) { - psTraceInfo("Need additional hash support for certVerify\n"); + psTraceErrr("Need additional hash support for certVerify\n"); return MATRIXSSL_ERROR; } *c = b1; c++; @@ -7505,7 +7629,7 @@ static int32 writeCertificateVerify(ssl_t *ssl, sslBuf_t *out) } else { - psTraceInfo("Need additional hash support for certVerify\n"); + psTraceErrr("Need additional hash support for certVerify\n"); return MATRIXSSL_ERROR; } *c = 0x1; c++; /* RSA */ @@ -7513,7 +7637,7 @@ static int32 writeCertificateVerify(ssl_t *ssl, sslBuf_t *out) # endif /* USE_PKCS1_PSS */ else { - psTraceInfo("Need additional hash support for certVerify\n"); + psTraceErrr("Need additional hash support for certVerify\n"); return MATRIXSSL_ERROR; } @@ -7549,7 +7673,7 @@ static int32 writeCertificateVerify(ssl_t *ssl, sslBuf_t *out) # endif # else /* RSA is the 'default' so if that didn't get hit there is a problem */ - psTraceInfo("There is no handler for writeCertificateVerify. ERROR\n"); + psTraceErrr("There is no handler for writeCertificateVerify. ERROR\n"); return MATRIXSSL_ERROR; # endif /* USE_RSA */ # ifdef USE_ECC diff --git a/matrixssl/sslv3.c b/matrixssl/sslv3.c index b020cff..1d780d6 100644 --- a/matrixssl/sslv3.c +++ b/matrixssl/sslv3.c @@ -138,7 +138,7 @@ skipPremaster: if (createKeyBlock(ssl, ssl->sec.clientRandom, ssl->sec.serverRandom, ssl->sec.masterSecret) < 0) { - psTraceInfo("Unable to create key block\n"); + psTraceErrr("Unable to create key block\n"); return PS_FAILURE; } diff --git a/matrixssl/test/Makefile b/matrixssl/test/Makefile index d184f43..f1250ca 100644 --- a/matrixssl/test/Makefile +++ b/matrixssl/test/Makefile @@ -15,6 +15,10 @@ STATIC:=../libssl_s.a $(MATRIXSSL_ROOT)/crypto/libcrypt_s.a $(MATRIXSSL_ROOT)/co include $(MATRIXSSL_ROOT)/common.mk +#ifdef USE_ROT_CRYPTO +STATIC+=$(LIBDRIVER_VAL_UP_PATH) +#endif + # Include possible additional MatrixSSL test program build instructions -include Makefile.add @@ -47,13 +51,13 @@ compile: $(OBJS) $(CERT_EXE) $(TEST_EXE) $(OBJS): $(MATRIXSSL_ROOT)/common.mk Makefile $(wildcard *.h) $(TEST_EXE): $(TEST_SRC:.c=.o) $(STATIC) - $(CC) -o $@ $^ $(LDFLAGS) + $(CC) -o $@ $^ $(EXTRA_CFLAGS) $(LDFLAGS) $(CERT_EXE): $(CERT_SRC:.c=.o) $(STATIC) - $(CC) -o $@ $^ $(LDFLAGS) + $(CC) -o $@ $^ $(EXTRA_CFLAGS) $(LDFLAGS) $(PROVIDER_EXE): $(PROVIDER_SRC:.c=.o) $(STATIC) - $(CC) -o $@ $^ $(LDFLAGS) + $(CC) -o $@ $^ $(EXTRA_CFLAGS) $(LDFLAGS) clean: rm -f $(TEST_EXE) $(CERT_EXE) $(PROVIDER_EXE) $(OBJS) $(CLEAN_EXTRA_FILES) *.map diff --git a/matrixssl/test/sslTest.c b/matrixssl/test/sslTest.c index 19cdef7..c7f34c3 100644 --- a/matrixssl/test/sslTest.c +++ b/matrixssl/test/sslTest.c @@ -37,7 +37,9 @@ # define _POSIX_C_SOURCE 200112L #endif -#include "matrixssl/matrixsslApi.h" +#include "matrixssl/matrixsslImpl.h" +#include + #include "psUtil.h" #include "psStat.h" #include "osdep_stdio.h" @@ -60,7 +62,7 @@ for each enabled cipher suite. The other handshake types will still run but will not be timed */ -/* #define ENABLE_PERF_TIMING */ +// #define ENABLE_PERF_TIMING #if !defined(POSIX) && !defined(WIN32) # define EMBEDDED @@ -154,6 +156,15 @@ int main(void) # endif # endif +# ifdef SSL_REHANDSHAKES_ENABLED +/* re-handshake for DTLS doesn't work with current test framework, therefore + it is disabled. XXX: Need to figure out what is the cause, although + rehandshaking is is a bad idea in general. */ +static bool testLoss = false; +# else +static bool testLoss = true; +# endif + typedef struct { ssl_t *ssl; @@ -287,7 +298,6 @@ static char dhParamFile[] = "../../testkeys/DH/3072_DH_PARAMS.pem"; # endif /* REQUIRE_DH_PARAMS */ # endif /* USE_FILE_SYSTEM_KEYS */ -# ifdef USE_RSA # include "testkeys/RSA/1024_RSA_KEY.h" # include "testkeys/RSA/1024_RSA.h" # include "testkeys/RSA/1024_RSA_CA.h" @@ -302,7 +312,6 @@ static char dhParamFile[] = "../../testkeys/DH/3072_DH_PARAMS.pem"; # include "testkeys/RSA/4096_RSA_CA.h" static __THREAD const unsigned char *RSAKEY, *RSACERT, *RSACA; static __THREAD uint32_t RSAKEY_SIZE, RSA_SIZE, RSACA_SIZE; -# endif /* USE_RSA */ # ifdef USE_ECC # include "testkeys/EC/192_EC_KEY.h" @@ -496,6 +505,8 @@ const static __THREAD char *g_version_str[] = { # define CS(A) { #A, A } const static __THREAD testCipherSpec_t ciphers[] = { + + /* TLS1.3 */ #ifdef USE_TLS_AES_128_GCM_SHA256 CS(TLS_AES_128_GCM_SHA256), @@ -890,6 +901,9 @@ int main(int argc, char **argv) return EXIT_FAILURE; } +#ifdef USE_DTLS + matrixDtlsSetPmtu(1350); +#endif if (num_threads > 1) { /* Multi-threaded test. */ @@ -962,7 +976,7 @@ psBool_t testCiphersuite(const testCipherSpec_t *spec) psBool_t testProtocolVersion(uint32_t version) { - /* No run-time restrictions unless USE_VERION_LIST is given. */ + /* No run-time restrictions unless USE_VERSION_LIST is given. */ if (!Getenv("USE_VERSION_LIST")) { return PS_TRUE; @@ -1020,6 +1034,459 @@ psBool_t testProtocolVersion(uint32_t version) return PS_FALSE; } +# ifdef USE_ECC +static +psBool_t testCurve(psSizeL_t curveSize) +{ + psBool_t checkEnv = PS_FALSE; + + if (Getenv("USE_CURVE_LIST")) + { + checkEnv = PS_TRUE; + } + +# ifdef USE_SECP192R1 + if (curveSize == EC192_SIZE) + { + if (!checkEnv) + { + return PS_TRUE; + } + if (Getenv("P_192")) + { + return PS_TRUE; + } + } +# endif + +# ifdef USE_SECP224R1 + if (curveSize == EC224_SIZE) + { + if (!checkEnv) + { + return PS_TRUE; + } + if (Getenv("P_224")) + { + return PS_TRUE; + } + } +# endif + +# ifdef USE_SECP256R1 + if (curveSize == EC256_SIZE) + { + if (!checkEnv) + { + return PS_TRUE; + } + if (Getenv("P_256")) + { + return PS_TRUE; + } + } +# endif + +# ifdef USE_SECP384R1 + if (curveSize == EC384_SIZE) + { + if (!checkEnv) + { + return PS_TRUE; + } + if (Getenv("P_384")) + { + return PS_TRUE; + } + } +# endif + +# ifdef USE_SECP521R1 + if (curveSize == EC521_SIZE) + { + if (!checkEnv) + { + return PS_TRUE; + } + if (Getenv("P_521")) + { + return PS_TRUE; + } + } +# endif + + return PS_FALSE; +} + +static +uint32_t getNextCurveSize(uint32_t oldSize) +{ + uint32_t newSize; + + newSize = oldSize; + + if (oldSize == 0) + { + newSize = EC192_SIZE; + } + else if (oldSize == EC192_SIZE) + { + newSize = EC224_SIZE; + } + else if (oldSize == EC224_SIZE) + { + newSize = EC256_SIZE; + } + else if (oldSize == EC256_SIZE) + { + newSize = EC384_SIZE; + } + else if (oldSize == EC384_SIZE) + { + newSize = EC521_SIZE; + } + else if (oldSize == EC521_SIZE) + { + newSize = 0; + } + + if (newSize != 0 && !testCurve(newSize)) + { + /* Config won't support, or user does not want to test + this curve. Go recursive to get the next one. */ + return getNextCurveSize(newSize); + } + + return newSize; +} + +static +void getEccCurve(uint32_t curveSize, + const unsigned char **eccKey, + uint32_t *eccKeySize, + const unsigned char **eccCert, + uint32_t *eccCertSize, + const unsigned char **eccCa, + uint32_t *eccCaSize, + psSize_t *keySizeNBits) +{ + switch(curveSize) + { +# ifdef USE_SECP192R1 + case EC192_SIZE: + *eccKey = EC192KEY; + *eccKeySize = EC192KEY_SIZE; + *eccCert = EC192; + *eccCertSize = EC192_SIZE; + *eccCa = EC192CA; + *eccCaSize = EC192CA_SIZE; + *keySizeNBits = 192; + break; +# endif +# ifdef USE_SECP224R1 + case EC224_SIZE: + *eccKey = EC224KEY; + *eccKeySize = EC224KEY_SIZE; + *eccCert = EC224; + *eccCertSize = EC224_SIZE; + *eccCa = EC224CA; + *eccCaSize = EC224CA_SIZE; + *keySizeNBits = 224; + break; +# endif +# ifdef USE_SECP256R1 + case EC256_SIZE: + *eccKey = EC256KEY; + *eccKeySize = EC256KEY_SIZE; + *eccCert = EC256; + *eccCertSize = EC256_SIZE; + *eccCa = EC256CA; + *eccCaSize = EC256CA_SIZE; + *keySizeNBits = 256; + break; +# endif +# ifdef USE_SECP384R1 + case EC384_SIZE: + *eccKey = EC384KEY; + *eccKeySize = EC384KEY_SIZE; + *eccCert = EC384; + *eccCertSize = EC384_SIZE; + *eccCa = EC384CA; + *eccCaSize = EC384CA_SIZE; + *keySizeNBits = 384; + break; +# endif +# ifdef USE_SECP521R1 + case EC521_SIZE: + *eccKey = EC521KEY; + *eccKeySize = EC521KEY_SIZE; + *eccCert = EC521; + *eccCertSize = EC521_SIZE; + *eccCa = EC521CA; + *eccCaSize = EC521CA_SIZE; + *keySizeNBits = 521; + break; +# endif + default: + testTrace("Unsupported ECC size\n"); + } + + return; +} + +# endif + +int32_t setSigAlgs(sslSessOpts_t *sessOpts) +{ + /* + List A: Prefer SHA-384 over SHA-256. + List B: Prefer RSA over ECDSA and RSA-PSS over RSA PKCS #1.5 + List C: Like list B, but prefer SHA-384 over SHA-256. + */ + uint16_t tls12ListA[] = + { + sigalg_rsa_pkcs1_sha384, + sigalg_rsa_pkcs1_sha256, + sigalg_rsa_pkcs1_sha512, + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp521r1_sha512, + sigalg_rsa_pkcs1_sha1, + sigalg_ecdsa_sha1 + }; + uint16_t tls12ListB[] = + { + sigalg_rsa_pkcs1_sha256, + sigalg_rsa_pkcs1_sha384, + sigalg_rsa_pkcs1_sha512, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp521r1_sha512, + sigalg_rsa_pkcs1_sha1, + sigalg_ecdsa_sha1 + }; + uint16_t tls12ListC[] = + { + sigalg_rsa_pkcs1_sha384, + sigalg_rsa_pkcs1_sha256, + sigalg_rsa_pkcs1_sha512, + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp521r1_sha512, + sigalg_rsa_pkcs1_sha1, + sigalg_ecdsa_sha1 + }; + uint16_t tls13ListA[] = + { + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp521r1_sha512, +# ifdef USE_ED25519 + sigalg_ed25519, +# endif +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha384, + sigalg_rsa_pss_rsae_sha256, + sigalg_rsa_pss_rsae_sha512, + sigalg_rsa_pss_pss_sha384, + sigalg_rsa_pss_pss_sha256, + sigalg_rsa_pss_pss_sha512 +# endif + }; + uint16_t tls13ListB[] = + { +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha256, + sigalg_rsa_pss_rsae_sha384, + sigalg_rsa_pss_rsae_sha512, + sigalg_rsa_pss_pss_sha256, + sigalg_rsa_pss_pss_sha384, + sigalg_rsa_pss_pss_sha512, +# endif + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp521r1_sha512, +# ifdef USE_ED25519 + sigalg_ed25519, +# endif + }; + uint16_t tls13ListC[] = + { +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha384, + sigalg_rsa_pss_rsae_sha256, + sigalg_rsa_pss_rsae_sha512, + sigalg_rsa_pss_pss_sha256, + sigalg_rsa_pss_pss_sha384, + sigalg_rsa_pss_pss_sha512, +# endif + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp521r1_sha512, +# ifdef USE_ED25519 + sigalg_ed25519, +# endif + }; + uint16_t tls13ListCertA[] = + { + sigalg_rsa_pkcs1_sha384, + sigalg_rsa_pkcs1_sha256, + sigalg_rsa_pkcs1_sha512, + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp521r1_sha512, +# ifdef USE_ED25519 + sigalg_ed25519, +# endif +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha384, + sigalg_rsa_pss_rsae_sha256, + sigalg_rsa_pss_rsae_sha512, + sigalg_rsa_pss_pss_sha384, + sigalg_rsa_pss_pss_sha256, + sigalg_rsa_pss_pss_sha512, +# endif + }; + uint16_t tls13ListCertB[] = + { + sigalg_rsa_pkcs1_sha256, + sigalg_rsa_pkcs1_sha384, + sigalg_rsa_pkcs1_sha512, + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp521r1_sha512, +# ifdef USE_ED25519 + sigalg_ed25519, +# endif +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha256, + sigalg_rsa_pss_rsae_sha384, + sigalg_rsa_pss_rsae_sha512, + sigalg_rsa_pss_pss_sha384, + sigalg_rsa_pss_pss_sha256, + sigalg_rsa_pss_pss_sha512 +# endif + }; + uint16_t tls13ListCertC[] = + { + sigalg_rsa_pkcs1_sha384, + sigalg_rsa_pkcs1_sha256, + sigalg_rsa_pkcs1_sha512, + sigalg_ecdsa_secp384r1_sha384, + sigalg_ecdsa_secp256r1_sha256, + sigalg_ecdsa_secp521r1_sha512, +# ifdef USE_ED25519 + sigalg_ed25519, +# endif +# ifdef USE_PKCS1_PSS + sigalg_rsa_pss_rsae_sha384, + sigalg_rsa_pss_rsae_sha256, + sigalg_rsa_pss_rsae_sha512, + sigalg_rsa_pss_pss_sha384, + sigalg_rsa_pss_pss_sha256, + sigalg_rsa_pss_pss_sha512 +# endif + }; + + uint16_t *list = NULL, *listCert; + psSize_t listLen, listCertLen; + int32_t rc; + psBool_t tls13 = PS_FALSE; + + if (sessOpts->versionFlag & SSL_FLAGS_TLS_1_3) + { + tls13 = PS_TRUE; + } + + if (Getenv("USE_SIGALG_LIST")) + { + if (Getenv("SIGALG_LIST_A")) + { + printf("Using list A\n"); + if (tls13) + { + list = tls13ListA; + listLen = sizeof(tls13ListA)/sizeof(tls13ListA[0]); + listCert = tls13ListCertA; + listCertLen = sizeof(tls13ListCertA)/sizeof(tls13ListCertA[0]); + } + else + { + list = tls12ListA; + listLen = sizeof(tls12ListA)/sizeof(tls12ListA[0]); + } + } + if (Getenv("SIGALG_LIST_B")) + { + printf("Using list B\n"); + if (tls13) + { + list = tls13ListB; + listLen = sizeof(tls13ListB)/sizeof(tls13ListB[0]); + listCert = tls13ListCertB; + listCertLen = sizeof(tls13ListCertB)/sizeof(tls13ListCertB[0]); + } + else + { + list = tls12ListB; + listLen = sizeof(tls12ListB)/sizeof(tls12ListB[0]); + } + } + if (Getenv("SIGALG_LIST_C")) + { + printf("Using list C\n"); + if (tls13) + { + list = tls13ListC; + listLen = sizeof(tls13ListC)/sizeof(tls13ListC[0]); + listCert = tls13ListCertC; + listCertLen = sizeof(tls13ListCertC)/sizeof(tls13ListCertC[0]); + } + else + { + list = tls12ListC; + listLen = sizeof(tls12ListC)/sizeof(tls12ListC[0]); + } + } + + if (list != NULL) + { + psTracePrintTls13SigAlgList(0, + "Using sigalg preferences:", + list, + listLen, + PS_TRUE); + + rc = matrixSslSessOptsSetSigAlgs(sessOpts, + list, + listLen); + if (rc != PS_SUCCESS) + { + return rc; + } + +# ifdef USE_TLS_1_3 + if (tls13) + { + rc = matrixSslSessOptsSetSigAlgsCert(sessOpts, + listCert, + listCertLen); + if (rc != PS_SUCCESS) + { + return rc; + } + } +# else + (void)listCert; + (void)listCertLen; +# endif + } + } + + return PS_SUCCESS; +} + + int sslTest(void) { sslConn_t *svrConn, *clnConn; @@ -1102,7 +1569,7 @@ L_NEXT_RSA: keysize = authsize = 3072; break; case RSA3072_SIZE: -# if !defined(EMBEDDED) && !defined(USE_CL_CRYPTO) +# if !defined(EMBEDDED) && !defined(USE_CL_CRYPTO) && !defined(USE_ROT_RSA) RSAKEY = RSA4096KEY; RSAKEY_SIZE = RSA4096KEY_SIZE; RSACERT = RSA4096; RSA_SIZE = RSA4096_SIZE; RSACA = RSA4096CA; RSACA_SIZE = RSA4096CA_SIZE; @@ -1146,80 +1613,17 @@ L_NEXT_RSA: L_NEXT_ECC: if (spec->type == CS_ECDH_ECDSA || spec->type == CS_ECDHE_ECDSA) { - switch (ECC_SIZE) - { - case 0: -# ifdef USE_SECP192R1 - ECCKEY = EC192KEY; ECCKEY_SIZE = EC192KEY_SIZE; - ECC = EC192; ECC_SIZE = EC192_SIZE; - ECCCA = EC192CA; ECCCA_SIZE = EC192CA_SIZE; - keysize = authsize = 192; - break; -# else -# ifdef USE_SECP224R1 - /* P-192 skipped. */ - ECCKEY = EC224KEY; ECCKEY_SIZE = EC224KEY_SIZE; - ECC = EC224; ECC_SIZE = EC224_SIZE; - ECCCA = EC224CA; ECCCA_SIZE = EC224CA_SIZE; - keysize = authsize = 224; - break; -# else - /* P-192 and P-224 skipped. */ - ECCKEY = EC256KEY; ECCKEY_SIZE = EC256KEY_SIZE; - ECC = EC256; ECC_SIZE = EC256_SIZE; - ECCCA = EC256CA; ECCCA_SIZE = EC256CA_SIZE; - keysize = authsize = 256; - break; -# endif /* USE_SECP224R1 */ -# endif /* USE_SECP192R1 */ - case EC192_SIZE: -# ifdef USE_SECP224R1 - ECCKEY = EC224KEY; ECCKEY_SIZE = EC224KEY_SIZE; - ECC = EC224; ECC_SIZE = EC224_SIZE; - ECCCA = EC224CA; ECCCA_SIZE = EC224CA_SIZE; - keysize = authsize = 224; - break; -# else - /* P-224 skipped. */ - ECCKEY = EC256KEY; ECCKEY_SIZE = EC256KEY_SIZE; - ECC = EC256; ECC_SIZE = EC256_SIZE; - ECCCA = EC256CA; ECCCA_SIZE = EC256CA_SIZE; - keysize = authsize = 256; - break; -# endif /* USE_SECP224R1 */ - case EC224_SIZE: - ECCKEY = EC256KEY; ECCKEY_SIZE = EC256KEY_SIZE; - ECC = EC256; ECC_SIZE = EC256_SIZE; - ECCCA = EC256CA; ECCCA_SIZE = EC256CA_SIZE; - keysize = authsize = 256; - break; - case EC256_SIZE: -# ifndef EMBEDDED - ECCKEY = EC384KEY; ECCKEY_SIZE = EC384KEY_SIZE; - ECC = EC384; ECC_SIZE = EC384_SIZE; - ECCCA = EC384CA; ECCCA_SIZE = EC384CA_SIZE; - keysize = authsize = 384; - break; - case EC384_SIZE: -# ifdef USE_SECP521R1 - ECCKEY = EC521KEY; ECCKEY_SIZE = EC521KEY_SIZE; - ECC = EC521; ECC_SIZE = EC521_SIZE; - ECCCA = EC521CA; ECCCA_SIZE = EC521CA_SIZE; - keysize = authsize = 521; - break; -# else - /* P-521 skipped. */ - ECC_SIZE = 0; -# endif /* USE_SECP521R1 */ - case EC521_SIZE: -# endif /* !EMBEDDED */ - ECC_SIZE = 0; - break; - } + ECC_SIZE = getNextCurveSize(ECC_SIZE); if (ECC_SIZE == 0) { continue; /* Next cipher suite */ } + getEccCurve(ECC_SIZE, + &ECCKEY, &ECCKEY_SIZE, + &ECC, &ECC_SIZE, + &ECCCA, &ECCCA_SIZE, + &keysize); + authsize = keysize; } # endif /* USE_ECC */ @@ -1450,39 +1854,39 @@ L_NEXT_DH: # if defined(SSL_REHANDSHAKES_ENABLED) && !defined(USE_ZLIB_COMPRESSION) # ifdef DISABLE_DTLS_CLIENT_CHANGE_CIPHER_FROM_GCM_TO_GCM if (NGTD_VER(clnConn->ssl, v_dtls_any) && - clnConn->ssl->cipher->flags & CRYPTO_FLAGS_GCM && - spec->flags & CRYPTO_FLAGS_GCM) - { - testPrint(" Re-handshakes with a GCM-to-GCM change are disabled\n"); - goto skip_client_initiated_rehandshake; - } + clnConn->ssl->cipher->flags & CRYPTO_FLAGS_GCM && + spec->flags & CRYPTO_FLAGS_GCM) + { + testPrint(" Re-handshakes with a GCM-to-GCM change are disabled\n"); + goto skip_client_initiated_rehandshake; + } # endif /* DISABLE_DTLS_CLIENT_CHANGE_CIPHER_FROM_GCM_TO_GCM */ /* Re-Handshake (full handshake over existing connection) */ - testTrace(" Re-handshake test (client-initiated)\n"); - if (initializeReHandshake(clnConn, svrConn, ciphers[id].id) < 0) + testTrace(" Re-handshake test (client-initiated)\n"); + if (initializeReHandshake(clnConn, svrConn, ciphers[id].id) < 0) + { + testPrint(" FAILED: initializing Re-handshake\n"); + goto LBL_FREE; + } + if (performHandshake(clnConn, svrConn) < 0) + { + testPrint(" FAILED: Re-handshake\n"); + goto LBL_FREE; + } + else + { + testTrace(" PASSED: Re-handshake"); + if (exchangeAppData(clnConn, svrConn, CLI_APP_DATA) < 0 || + exchangeAppData(svrConn, clnConn, SVR_APP_DATA) < 0) { - testPrint(" FAILED: initializing Re-handshake\n"); - goto LBL_FREE; - } - if (performHandshake(clnConn, svrConn) < 0) - { - testPrint(" FAILED: Re-handshake\n"); + testPrint(" but FAILED to exchange application data\n"); goto LBL_FREE; } else { - testTrace(" PASSED: Re-handshake"); - if (exchangeAppData(clnConn, svrConn, CLI_APP_DATA) < 0 || - exchangeAppData(svrConn, clnConn, SVR_APP_DATA) < 0) - { - testPrint(" but FAILED to exchange application data\n"); - goto LBL_FREE; - } - else - { - testTrace("\n"); - } + testTrace("\n"); } + } # ifdef DISABLE_DTLS_CLIENT_CHANGE_CIPHER_FROM_GCM_TO_GCM skip_client_initiated_rehandshake: # endif /* DISABLE_DTLS_CLIENT_CHANGE_CIPHER_FROM_GCM_TO_GCM */ @@ -1492,7 +1896,7 @@ skip_client_initiated_rehandshake: # ifndef USE_ONLY_PSK_CIPHER_SUITE /* Resumed handshake (fast handshake over new connection) */ - testTrace(" Resumed handshake test (new connection)\n"); + testTrace(" Resumed handshake test (new connection)\n"); if (initializeResumedHandshake(clnConn, svrConn, ciphers[id].id) < 0) { @@ -1532,7 +1936,7 @@ skip_client_initiated_rehandshake: we're not doing that here so the cipher suite might be changing underneath us now. */ - testTrace(" Re-handshake test (server initiated)\n"); + testTrace(" Re-handshake test (server initiated)\n"); if (initializeServerInitiatedReHandshake(clnConn, svrConn, ciphers[id].id) < 0) { @@ -1907,6 +2311,7 @@ skip_client_change_cipher_spec_rehandshake: LBL_FREE: testPrint("EXITING ON ERROR\n"); # ifdef ABORT_IMMEDIATELY_ON_ERROR + matrixSslClose(); Abort(); # endif @@ -2110,6 +2515,12 @@ static int32 initializeResumedHandshake(sslConn_t *clnConn, sslConn_t *svrConn, Memset(&options, 0x0, sizeof(sslSessOpts_t)); options.versionFlag = g_versionFlag; + rc = setSigAlgs(&options); + if (rc < 0) + { + return rc; + } + # ifdef USE_ECC_CIPHER_SUITE options.ecFlags = clnConn->ssl->ecInfo.ecFlags; # endif @@ -2189,12 +2600,13 @@ static int32 initializeClientAuthHandshake(sslConn_t *clnConn, { sslSessOpts_t options; sslKeys_t *keys = clnConn->keys; - + int32_t rc; # ifdef ENABLE_PERF_TIMING psTime_t start, end; # endif /* ENABLE_PERF_TIMING */ Memset(&options, 0x0, sizeof(sslSessOpts_t)); + /* Set fragment size to minimum to test also fragmentation */ if (g_versionFlag & SSL_FLAGS_TLS_1_3) { @@ -2211,6 +2623,13 @@ static int32 initializeClientAuthHandshake(sslConn_t *clnConn, } } options.versionFlag = g_versionFlag; + + rc = setSigAlgs(&options); + if (rc < 0) + { + return rc; + } + # ifdef USE_ECC_CIPHER_SUITE options.ecFlags = clnConn->ssl->ecInfo.ecFlags; # endif @@ -2271,168 +2690,210 @@ static int32 initializeClientAuthHandshake(sslConn_t *clnConn, } # endif /* USE_CLIENT_AUTH */ +#ifdef ENABLE_PERF_TIMING +#define TIMED(side, expr) do { \ + psTime_t start, end; \ + psGetTime(&start, NULL); (expr); psGetTime(&end, NULL); \ + (side)->hsTime += psDiffMsecs(start, end, NULL); \ + } while(0) +#else +#define TIMED(side, expr) do { (expr); } while (0) +#endif + +static void *memdup(void *src, size_t len) +{ + void *dst = psMalloc(NULL, len + 1); + memcpy(dst, src, len); + return dst; +} + +static void freefrags(int nfrags, unsigned char *frags[]) +{ + int i; + for (i = 0; i < nfrags; i++) + { + psFree(frags[i], NULL); + } +} + /* Recursive handshake */ static int32 performHandshake(sslConn_t *sendingSide, sslConn_t *receivingSide) { - unsigned char *inbuf, *outbuf, *plaintextBuf; - int32 inbufLen, outbufLen, rc, dataSent; + unsigned char *inbuf, *plaintextBuf; + int32 inbufLen, rc, dataSent; uint32 ptLen; - -# ifdef ENABLE_PERF_TIMING - psTime_t start, end; -# endif /* ENABLE_PERF_TIMING */ - -/* - Sending side will have outdata ready - */ -# ifdef ENABLE_PERF_TIMING - psGetTime(&start, NULL); -# endif /* ENABLE_PERF_TIMING */ # ifdef USE_DTLS - if (NGTD_VER(sendingSide->ssl, v_dtls_any)) + bool sendServer = (sendingSide->ssl->flags & SSL_FLAGS_SERVER); + int retries = 0; +# endif + unsigned char *frags[24] = {NULL}; + int32 frag_lens[24] = {0}; + int nfrags, ndrops; + int i; + + /* + Sending side will have outdata ready + */ + +again: + if (ACTV_VER(sendingSide->ssl, v_dtls_any)) { - outbufLen = matrixDtlsGetOutdata(sendingSide->ssl, &outbuf); +# ifdef USE_DTLS + TIMED(sendingSide, { + /* Collect data ready to be sent */ + nfrags = 0; + while (true) + { + unsigned char *frag; + frag_lens[nfrags] = matrixDtlsGetOutdata(sendingSide->ssl, &frag); + if (frag_lens[nfrags] == 0) + { + break; + } + /* the SentData will shrink the internal buffer, therefore need to copy */ + frags[nfrags] = (unsigned char *)memdup(frag, frag_lens[nfrags]); + matrixDtlsSentData(sendingSide->ssl, frag_lens[nfrags]); + nfrags++; + } + }); +# endif } else { - outbufLen = matrixSslGetOutdata(sendingSide->ssl, &outbuf); + TIMED(sendingSide, { + unsigned char *frag; + nfrags = 0; + frag_lens[nfrags] = matrixSslGetOutdata(sendingSide->ssl, &frag); + frags[nfrags] = (unsigned char *)memdup(frag, frag_lens[nfrags]); + matrixSslSentData(sendingSide->ssl, frag_lens[nfrags]); + nfrags = 1; + }); } -# else - outbufLen = matrixSslGetOutdata(sendingSide->ssl, &outbuf); -# endif -# ifdef ENABLE_PERF_TIMING - psGetTime(&end, NULL); - sendingSide->hsTime += psDiffMsecs(start, end, NULL); -# endif /* ENABLE_PERF_TIMING */ -/* - Receiving side must ask for storage space to receive data into - */ -# ifdef ENABLE_PERF_TIMING - psGetTime(&start, NULL); -# endif /* ENABLE_PERF_TIMING */ - inbufLen = matrixSslGetReadbuf(receivingSide->ssl, &inbuf); -# ifdef ENABLE_PERF_TIMING - psGetTime(&end, NULL); - receivingSide->hsTime += psDiffMsecs(start, end, NULL); -# endif /* ENABLE_PERF_TIMING */ + ndrops = 0; -/* - The indata is the outdata from the sending side. copy it over - */ - if (outbufLen <= 0 || inbufLen <= 0) + /* Now play potentially unreliable network. However, never drop messages + sent by server, as this test driver can't handle server side + retransmits properly. */ + if (ACTV_VER(sendingSide->ssl, v_dtls_any)) { - return PS_FAILURE; - } - dataSent = PS_MIN(outbufLen, inbufLen); - Memcpy(inbuf, outbuf, dataSent); - -/* - Now update the sending side that data has been "sent" - */ -# ifdef ENABLE_PERF_TIMING - psGetTime(&start, NULL); -# endif /* ENABLE_PERF_TIMING */ -# ifdef USE_DTLS - if (NGTD_VER(sendingSide->ssl, v_dtls_any)) - { - matrixDtlsSentData(sendingSide->ssl, dataSent); - } - else - { - matrixSslSentData(sendingSide->ssl, dataSent); - } -# else - matrixSslSentData(sendingSide->ssl, dataSent); -# endif -# ifdef ENABLE_PERF_TIMING - psGetTime(&end, NULL); - sendingSide->hsTime += psDiffMsecs(start, end, NULL); -# endif /* ENABLE_PERF_TIMING */ - -/* - Received data - */ -# ifdef ENABLE_PERF_TIMING - psGetTime(&start, NULL); -# endif /* ENABLE_PERF_TIMING */ - rc = matrixSslReceivedData(receivingSide->ssl, dataSent, &plaintextBuf, - &ptLen); -# ifdef ENABLE_PERF_TIMING - psGetTime(&end, NULL); - receivingSide->hsTime += psDiffMsecs(start, end, NULL); -# endif /* ENABLE_PERF_TIMING */ - -# ifdef USE_EXT_CLIENT_CERT_KEY_LOADING - if (rc == PS_PENDING && matrixSslNeedClientCert(receivingSide->ssl)) - { - /* Well... we already have the keys read in */ - (void)matrixSslClientCertUpdated(receivingSide->ssl); - /* Retry now that we have the cert and the priv key. */ - rc = matrixSslReceivedData(receivingSide->ssl, - dataSent, - &plaintextBuf, &ptLen); - } -# endif - -# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING -# endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ -# ifdef USE_EXT_CLIENT_CERT_KEY_LOADING - if (rc == PS_PENDING && matrixSslNeedClientCert(receivingSide->ssl)) - { - /* We have already loaded a client cert we can use in this test, - so do nothing. */ - rc = matrixSslClientCertUpdated(receivingSide->ssl); - psAssert(rc == PS_TRUE); - rc = matrixSslReceivedData(receivingSide->ssl, dataSent, &plaintextBuf, - &ptLen); - } -# endif /* USE_EXT_CLIENT_CERT_KEY_LOADING */ - if (rc == MATRIXSSL_REQUEST_SEND) - { -/* - Success case. Switch roles and continue - */ - return performHandshake(receivingSide, sendingSide); - - } - else if (rc == MATRIXSSL_REQUEST_RECV) - { -/* - This pass didn't take care of it all. Don't switch roles and - try again - */ - return performHandshake(sendingSide, receivingSide); - - } - else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) - { - return PS_SUCCESS; - } - else if (rc == MATRIXSSL_RECEIVED_ALERT) - { -/* - Just continue if warning level alert - */ - if (plaintextBuf[0] == SSL_ALERT_LEVEL_WARNING) + for (i = 0; testLoss && i < nfrags; i++) { - if (matrixSslProcessedData(receivingSide->ssl, &plaintextBuf, - &ptLen) != 0) +# ifdef USE_DTLS + if (!sendServer) { - return PS_FAILURE; + if (rand() % 3 == 0) + { + retries++; + for (i = 0; i < nfrags; i++) + { + /* maybe drop some of the fragments */ + if (rand() % 3 == 0) + { + printf("dropped %d bytes for %d time on sending %s %d/%d frag \n", frag_lens[i], retries, + sendServer ? "server": "client", i+1, nfrags); + psFree(frags[i], NULL); frags[i] = NULL; + ndrops++; + } + } + if (ndrops == nfrags) + { + /* dropped all ... as nothing was sent we'll + resend after zero timeout. */ + freefrags(nfrags, frags); + goto again; + } + } } - return performHandshake(sendingSide, receivingSide); - } - else - { - return PS_FAILURE; +# endif } } - Printf("Unexpected error in performHandshake: %d\n", rc); - return PS_FAILURE; + rc = PS_FAILURE; + /* Received data */ + for (i = 1; i <= nfrags; i++) + { + int off; + + if (frags[i - 1] == NULL) + continue; + +# if (defined(USE_EXT_CERTIFICATE_VERIFY_SIGNING) && defined(USE_EXT_EXAMPLE_MODULE)) || \ + defined(USE_EXT_CLIENT_CERT_KEY_LOADING) + retry: +# endif + for (off = 0; off < frag_lens[i - 1]; off += dataSent) + { + TIMED(receivingSide, { + inbufLen = matrixSslGetReadbuf(receivingSide->ssl, &inbuf); + }); + + dataSent = PS_MIN((frag_lens[i - 1] - off), inbufLen); + Memcpy(inbuf, frags[i - 1] + off, dataSent); + TIMED(receivingSide, { + rc = matrixSslReceivedData(receivingSide->ssl, + dataSent, &plaintextBuf, &ptLen); + }); + + switch (rc) + { + case PS_PENDING: +# ifdef USE_EXT_CLIENT_CERT_KEY_LOADING + if (matrixSslNeedClientCert(receivingSide->ssl)) + { + /* Well... we already have the keys read in */ + (void)matrixSslClientCertUpdated(receivingSide->ssl); + /* Retry now that we have the cert and the priv key. */ + goto retry; + }; +# endif + + psAssert(false); + break; + + case MATRIXSSL_REQUEST_SEND: + if (i < nfrags) + { + /* Handle all fragments received, only send the response + on the last */ + continue; + } + freefrags(nfrags, frags); + return performHandshake(receivingSide, sendingSide); + + case MATRIXSSL_REQUEST_RECV: + /* Feed more data */ + psAssert(i < nfrags || off < frag_lens[i - 1]); + continue; + + case MATRIXSSL_HANDSHAKE_COMPLETE: + psAssert(i == nfrags); + freefrags(nfrags, frags); + return PS_SUCCESS; + + case MATRIXSSL_RECEIVED_ALERT: + /* Just continue if warning level alert */ + if (plaintextBuf[0] == SSL_ALERT_LEVEL_WARNING) + { + continue; + } + else + { + freefrags(nfrags, frags); + return PS_FAILURE; + } + } + } + } + freefrags(nfrags, frags); + if (ndrops > 0 + && (rc == MATRIXSSL_REQUEST_SEND || rc == MATRIXSSL_REQUEST_RECV)) + { + goto again; + } + return rc; } @@ -2855,9 +3316,16 @@ static int32 initializeServer(sslConn_t *conn, psCipher16_t cipherSuite) # endif /* ENABLE_PERF_TIMING */ sslSessOpts_t options; const sslCipherSpec_t *spec; + int32_t rc; Memset(&options, 0x0, sizeof(sslSessOpts_t)); options.versionFlag = g_versionFlag; + rc = setSigAlgs(&options); + if (rc < 0) + { + return rc; + } + if (conn->keys == NULL) { if ((spec = sslGetDefinedCipherSpec(cipherSuite)) == NULL) @@ -2988,7 +3456,6 @@ static int32 initializeServer(sslConn_t *conn, psCipher16_t cipherSuite) conn->hsTime += psDiffMsecs(start, end, NULL); # endif /* ENABLE_PERF_TIMING */ conn->ssl = ssl; - return PS_SUCCESS; } @@ -2997,15 +3464,22 @@ static int32 initializeClient(sslConn_t *conn, psCipher16_t cipherSuite, { ssl_t *ssl; sslKeys_t *keys; - + int32_t rc; # ifdef ENABLE_PERF_TIMING psTime_t start, end; # endif /* ENABLE_PERF_TIMING */ sslSessOpts_t options; const sslCipherSpec_t *spec; + Memset(&options, 0x0, sizeof(sslSessOpts_t)); options.versionFlag = g_versionFlag; /* options.maxFragLen = 512; */ + rc = setSigAlgs(&options); + if (rc < 0) + { + return rc; + } + # ifdef TEST_RESUMPTIONS_WITH_SESSION_TICKETS options.ticketResumption = 1; # endif @@ -3232,6 +3706,13 @@ int tls13sslTest(void) algorithm = TLS13_PSK; break; } + +# ifndef USE_RSA + if (algorithm == TLS13_RSA) + { + continue; + } +# endif matrixSslNewSessionId(&clientSessionId, NULL); testPrintStr("Testing %s TLS 1.3 ", (char *) ciphers[id].name); if (algorithm != TLS13_PSK) @@ -3374,6 +3855,7 @@ error: testPrint("EXITING ON ERROR\n"); rc = PS_FAILURE; # ifdef ABORT_IMMEDIATELY_ON_ERROR + matrixSslClose(); Abort(); # endif /* ABORT_IMMEDIATELY_ON_ERROR */ @@ -3408,9 +3890,17 @@ static int32 tls13InitializeServer(sslConn_t *conn, psCipher16_t cipherSuite, ui unsigned char sessTicketMacKey[32] = { 0 }; unsigned char sessTicketName[16]; # endif + int32_t rc; Memset(&options, 0x0, sizeof(sslSessOpts_t)); + options.versionFlag = g_versionFlag; + rc = setSigAlgs(&options); + if (rc < 0) + { + return rc; + } + options.tls13SessionMaxEarlyData = 16384; if (Getenv("TLS13_BLOCK_SIZE")) { @@ -3488,16 +3978,23 @@ static int32 tls13InitializeServer(sslConn_t *conn, psCipher16_t cipherSuite, ui { const unsigned char *psk; uint32 pskLen; + const unsigned char *psk_id; + psSize_t psk_id_len; + psTls13SessionParams_t session; switch (cipherSuite) { case TLS_AES_256_GCM_SHA384: psk = g_tls13_test_psk_384; + psk_id = g_tls13_test_psk_id_sha384; + psk_id_len = sizeof(g_tls13_test_psk_id_sha384); pskLen = 48; break; default: psk = g_tls13_test_psk_256; + psk_id = g_tls13_test_psk_id_sha256; + psk_id_len = sizeof(g_tls13_test_psk_id_sha256); pskLen = 32; } @@ -3509,8 +4006,8 @@ static int32 tls13InitializeServer(sslConn_t *conn, psCipher16_t cipherSuite, ui if (matrixSslLoadTls13Psk(keys, psk, pskLen, - g_tls13_test_psk_id, - sizeof(g_tls13_test_psk_id), + psk_id, + psk_id_len, &session) < 0) { return PS_FAILURE; @@ -3559,9 +4056,18 @@ static int32 tls13InitializeClient(sslConn_t *conn, psCipher16_t cipherSuite, sslKeys_t *keys; sslSessOpts_t options; const sslCipherSpec_t *spec; + int32_t rc; Memset(&options, 0x0, sizeof(sslSessOpts_t)); + options.versionFlag = g_versionFlag; + + rc = setSigAlgs(&options); + if (rc < 0) + { + return rc; + } + if (Getenv("TLS13_BLOCK_SIZE")) { options.tls13BlockSize = Strtol(Getenv("TLS13_BLOCK_SIZE"), @@ -3666,16 +4172,22 @@ static int32 tls13InitializeClient(sslConn_t *conn, psCipher16_t cipherSuite, { const unsigned char *psk; uint32 pskLen; + const unsigned char *psk_id; + psSize_t psk_id_len; psTls13SessionParams_t session; switch (cipherSuite) { case TLS_AES_256_GCM_SHA384: psk = g_tls13_test_psk_384; + psk_id = g_tls13_test_psk_id_sha384; + psk_id_len = sizeof(g_tls13_test_psk_id_sha384); pskLen = 48; break; default: psk = g_tls13_test_psk_256; + psk_id = g_tls13_test_psk_id_sha256; + psk_id_len = sizeof(g_tls13_test_psk_id_sha256); pskLen = 32; } @@ -3687,8 +4199,8 @@ static int32 tls13InitializeClient(sslConn_t *conn, psCipher16_t cipherSuite, if (matrixSslLoadTls13Psk(keys, psk, pskLen, - g_tls13_test_psk_id, - sizeof(g_tls13_test_psk_id), + psk_id, + psk_id_len, &session) < 0) { return PS_FAILURE; diff --git a/matrixssl/tls.c b/matrixssl/tls.c index 5d56e98..6c4c8f7 100644 --- a/matrixssl/tls.c +++ b/matrixssl/tls.c @@ -49,6 +49,11 @@ # define LABEL_EXT_SIZE 22 # define LABEL_EXT_MASTERSEC "extended master secret" +/* Warning: enabling this will output the derived secrets to the + debug log. Enable only if debugging key derivation issues. */ +# ifndef DEBUG_TLS_LOG_SECRETS +/*# define DEBUG_TLS_LOG_SECRETS */ +# endif static int32_t genKeyBlock(ssl_t *ssl) { @@ -298,6 +303,7 @@ int32_t tlsExtendedDeriveKeys(ssl_t *ssl) # endif extMasterSecretSnapshotHSHash(ssl, hash, &outLen); + /* master_secret = PRF(pre_master_secret, "extended master secret", session_hash); @@ -335,6 +341,10 @@ int32_t tlsExtendedDeriveKeys(ssl_t *ssl) } # endif +# ifdef DEBUG_TLS_LOG_SECRETS + psTraceBytes("ssl->sec.masterSecret", ssl->sec.masterSecret, 48); +# endif + # ifdef USE_DTLS if (ACTV_VER(ssl, v_dtls_any)) { @@ -875,6 +885,7 @@ int32 sslActivateWriteCipher(ssl_t *ssl) Memcpy(&ssl->oencryptCtx, &ssl->sec.encryptCtx, sizeof(psCipherContext_t)); Memcpy(ssl->owriteIV, ssl->sec.writeIV, ssl->cipher->ivSize); + Memcpy(ssl->owriteKey, ssl->sec.writeKey, sizeof(ssl->owriteKey)); } } # endif /* USE_DTLS */ diff --git a/matrixssl/tls13Decode.c b/matrixssl/tls13Decode.c index 6a92549..30c770d 100644 --- a/matrixssl/tls13Decode.c +++ b/matrixssl/tls13Decode.c @@ -144,9 +144,9 @@ static int32_t tls13ParseServerHello(ssl_t *ssl, static int32_t tls13ParseCertificateRequest(ssl_t *ssl, psParseBuf_t *pb); # endif +# ifdef USE_CERT_VALIDATE static int32_t tls13ParseCertificate(ssl_t *ssl, psParseBuf_t *pb); -# ifdef USE_CERT_VALIDATE static int32_t tls13ParseCertificateVerify(ssl_t *ssl, psParseBuf_t *pb); # endif @@ -297,7 +297,7 @@ parse_next_record_header: decryptTo = pb.buf.start; /* In-situ decryption. */ if (ssl->decrypt(ssl, pb.buf.start, decryptTo, ssl->rec.len) < 0) { - if (IS_SERVER(ssl) && + if (MATRIX_IS_SERVER(ssl) && ssl->tls13ServerEarlyDataEnabled == PS_FALSE && ssl->extFlags.got_early_data == 1) { @@ -659,7 +659,7 @@ static int32_t tls13CheckHsState(ssl_t *ssl, - SSL_HS_TLS_1_3_WAIT_FINISHED (after having sent our Finished, but before having received the server Finished.) */ - else if (!IS_SERVER(ssl) && + else if (!MATRIX_IS_SERVER(ssl) && msg == SSL_HS_NEW_SESSION_TICKET && (ssl->hsState == SSL_HS_DONE || ssl->hsState == SSL_HS_TLS_1_3_WAIT_FINISHED)) @@ -987,7 +987,7 @@ static int32_t tls13ParseHandshakeMessage(ssl_t *ssl, goto exit; } - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { /* Transcript-Hash for ClientHello..Client Finished. */ rc = tls13TranscriptHashSnapshot(ssl, ssl->sec.tls13TrHashSnapshot); @@ -1452,7 +1452,7 @@ static int32_t tls13ParseCertificate(ssl_t *ssl, Empty certificate_list from the server: Always send an alert. */ - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { # ifdef SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG psTraceInfo("Received empty client certificate\n"); @@ -1621,7 +1621,9 @@ static int32_t tls13ParseCertificateVerify(ssl_t *ssl, psTracePrintTls13SigAlg(INDENT_HS_MSG, "algorithm", - algorithm, PS_TRUE); + algorithm, + PS_FALSE, + PS_TRUE); ssl->sec.tls13PeerCvSigAlg = algorithm; @@ -1657,8 +1659,8 @@ static int32_t tls13ParseCertificateVerify(ssl_t *ssl, algorithm, pb->buf.start, signatureLen, ssl->sec.tls13TrHashSnapshot, hashLen, - IS_SERVER(ssl) ? contextStrClient : contextStrServer, - IS_SERVER(ssl) ? Strlen(contextStrClient) : Strlen(contextStrServer)); + MATRIX_IS_SERVER(ssl) ? contextStrClient : contextStrServer, + MATRIX_IS_SERVER(ssl) ? Strlen(contextStrClient) : Strlen(contextStrServer)); if (rc < 0) { psTraceErrr("Could not verify peer signature\n"); @@ -1701,7 +1703,7 @@ static int32_t tls13ParseFinished(ssl_t *ssl, psParseBuf_t *pb) } /* Compute our version of the peer's verify_data. */ - rc = tls13DeriveFinishedKey(ssl, !IS_SERVER(ssl)); + rc = tls13DeriveFinishedKey(ssl, !MATRIX_IS_SERVER(ssl)); if (rc < 0) { goto out_internal_error; diff --git a/matrixssl/tls13DecodeExt.c b/matrixssl/tls13DecodeExt.c index b129f2f..821ae1f 100644 --- a/matrixssl/tls13DecodeExt.c +++ b/matrixssl/tls13DecodeExt.c @@ -38,7 +38,7 @@ # ifndef DEBUG_TLS_1_3_DECODE_EXTENSIONS /* # define DEBUG_TLS_1_3_DECODE_EXTENSIONS */ # endif -# ifdef DEBUG_TLS_1_3_ENCODE_EXTENSIONS +# ifdef DEBUG_TLS_1_3_DECODE_EXTENSIONS # warning "DEBUG_TLS_1_3_DECODE_EXTENSIONS will leak secrets into logs!" # endif @@ -158,7 +158,7 @@ int32_t tls13ParseStatusRequest(ssl_t *ssl, psTracePrintExtensionParse(ssl, EXT_STATUS_REQUEST); - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { /* Server parses the client request: @@ -448,8 +448,11 @@ psSize_t tls13ParseSupportedVersions(ssl_t *ssl, len -= 2; ver = psVerFromEncodingMajMin(majVer, minVer); - ADD_PEER_SUPP_VER(ssl, ver); - ADD_PEER_SUPP_VER_PRIORITY(ssl, ver); + if (ver != v_undefined) + { + ADD_PEER_SUPP_VER(ssl, ver); + ADD_PEER_SUPP_VER_PRIORITY(ssl, ver); + } i++; if (i >= TLS_MAX_SUPPORTED_VERSIONS) @@ -847,7 +850,15 @@ int32_t tls13ParsePreSharedKey(ssl_t *ssl, } PreSharedKeyExtension; */ - if (IS_SERVER(ssl)) + if (!SUPP_VER(ssl, v_tls_1_3_any)) + { + tlsTraceIndent(INDENT_EXTENSION, + "Ignoring this TLS 1.3 specific extension, " \ + "since TLS 1.3 not enabled\n"); + return MATRIXSSL_SUCCESS; + } + + if (MATRIX_IS_SERVER(ssl)) { /* PskIdentity identities<7..2^16-1>; */ rc = psParseBufParseTlsVector(pb, @@ -1019,7 +1030,7 @@ int32_t tls13ParsePskKeyExchangeModes(ssl_t *ssl, psBool_t gotPskKe = PS_FALSE; psBool_t gotPskDheKe = PS_FALSE; - psAssert(IS_SERVER(ssl)); + psAssert(MATRIX_IS_SERVER(ssl)); psTracePrintExtensionParse(ssl, EXT_PSK_KEY_EXCHANGE_MODES); /* @@ -1130,7 +1141,7 @@ int32_t tls13ParseCookie(ssl_t *ssl, goto out_unsupported_extension; } - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { # ifdef DEBUG_TLS_1_3_DECODE_EXTENSIONS psTraceBytes("Parsed ClientHello.cookie", @@ -1217,7 +1228,7 @@ int32_t tls13ParseServerName(ssl_t *ssl, server_name extension sent in EncryptedExtensions.) TLS <1.3 code path handles the ClientHello extension. */ - psAssert(!IS_SERVER(ssl)); + psAssert(!MATRIX_IS_SERVER(ssl)); psTracePrintExtensionParse(ssl, EXT_SERVER_NAME); # ifdef USE_CLIENT_SIDE_SSL /* Solicited or not? */ @@ -1252,7 +1263,7 @@ int32_t tls13ParseEarlyData(ssl_t *ssl, Only handling the client-side case (i.e. parsing the server's early_data extension sent in NewSessionTicket.) */ - psAssert(!IS_SERVER(ssl)); + psAssert(!MATRIX_IS_SERVER(ssl)); psTracePrintExtensionParse(ssl, EXT_EARLY_DATA); rc = psParseBufTryParseBigEndianUint32(pb, diff --git a/matrixssl/tls13Encode.c b/matrixssl/tls13Encode.c index 186f5a0..b792687 100644 --- a/matrixssl/tls13Encode.c +++ b/matrixssl/tls13Encode.c @@ -969,8 +969,8 @@ static int32 tls13WriteCertificate(ssl_t *ssl, sslBuf_t *out) /* certificate_request_context<0..2^8-1>; */ psDynBufAppendTlsVector(&certBuf, 0, (1 << 8) - 1, - IS_SERVER(ssl) ? NULL : ssl->tls13CertRequestContext, - IS_SERVER(ssl) ? 0 : ssl->tls13CertRequestContextLen); + MATRIX_IS_SERVER(ssl) ? NULL : ssl->tls13CertRequestContext, + MATRIX_IS_SERVER(ssl) ? 0 : ssl->tls13CertRequestContextLen); psDynBufInit(ssl->hsPool, &certListBuf, 4096); @@ -987,7 +987,7 @@ static int32 tls13WriteCertificate(ssl_t *ssl, sslBuf_t *out) Also note, that on client the code that selects client identity key pair should have already performed this check as part of the process. */ - if (!IS_SERVER(ssl)) + if (!MATRIX_IS_SERVER(ssl)) { if (c != NULL) { @@ -1146,7 +1146,9 @@ static int32 tls13WriteCertificateVerify(ssl_t *ssl, sslBuf_t *out) } psTracePrintTls13SigAlg(INDENT_HS_MSG, "Signing CertificateVerify with", - chosenSigAlg, PS_TRUE); + chosenSigAlg, + PS_FALSE, + PS_TRUE); ssl->sec.tls13CvSigAlg = chosenSigAlg; /* SignatureScheme algorithm; */ @@ -1180,7 +1182,7 @@ static int32 tls13WriteCertificateVerify(ssl_t *ssl, sslBuf_t *out) &ssl->chosenIdentity->privKey, chosenSigAlg, trHash, hmacLen, - IS_SERVER(ssl) ? contextStrServer : contextStrClient, + MATRIX_IS_SERVER(ssl) ? contextStrServer : contextStrClient, contextStrLen, &ssl->sec.tls13CvSig, &ssl->sec.tls13CvSigLen); @@ -1205,9 +1207,10 @@ static int32 tls13WriteCertificateVerify(ssl_t *ssl, sslBuf_t *out) (see C.3. in the draft spec.) When using crypto-cl, the self-verification has already - been done within CL/SL (CL_HashSafeSign). + been done within CL/SL (CL_HashSafeSign) + Same goes for RoT - self-verify is done within the RoT. */ -# ifndef USE_CL_RSA +# if !defined(USE_CL_RSA) && !defined(USE_ROT_RSA) verifyOwnSig = PS_TRUE; # endif } @@ -1224,7 +1227,7 @@ static int32 tls13WriteCertificateVerify(ssl_t *ssl, sslBuf_t *out) ssl->sec.tls13CvSig, ssl->sec.tls13CvSigLen, trHash, hmacLen, - IS_SERVER(ssl) ? contextStrServer : contextStrClient, + MATRIX_IS_SERVER(ssl) ? contextStrServer : contextStrClient, contextStrLen); if (rc < 0) { @@ -1307,7 +1310,7 @@ static int32 tls13WriteFinished(ssl_t *ssl, sslBuf_t *out) opaque verify_data[Hash.length]; } Finished; */ - rc = tls13DeriveFinishedKey(ssl, IS_SERVER(ssl)); + rc = tls13DeriveFinishedKey(ssl, MATRIX_IS_SERVER(ssl)); if (rc < 0 || hmacLen < 0) { return rc; @@ -1928,7 +1931,7 @@ int32 tls13EncodeResponseClient(ssl_t *ssl, psBuf_t *out, uint32 *requiredLen) int32 tls13EncodeResponse(ssl_t *ssl, psBuf_t *out, uint32 *requiredLen) { - switch(IS_SERVER(ssl)) + switch(MATRIX_IS_SERVER(ssl)) { #ifdef USE_SERVER_SIDE_SSL case PS_TRUE: @@ -2074,7 +2077,7 @@ int32_t tls13EncryptMessage(ssl_t *ssl, { return rc; } - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { /* Set-up HS read keys for the client's Finished message if early data is not expected to be received */ @@ -2178,7 +2181,7 @@ int32_t tls13EncodeAppData(ssl_t *ssl, recLen = (encryptEnd - encryptStart) + TLS_GCM_TAG_LEN; rc = tls13Encrypt(ssl, - ptBuf, + encryptStart, buf + TLS_REC_HDR_LEN, encryptEnd - encryptStart, SSL_RECORD_TYPE_APPLICATION_DATA, @@ -2429,22 +2432,33 @@ int32 tls13WriteClientHello(ssl_t *ssl, sslBuf_t *out, { /* Only use those cipher suites that were provided */ psDynBufInit(ssl->hsPool, &ciphersBuf, 32); - ssl->tls13ClientCipherSuitesLen = 0; - ssl->tls13ClientCipherSuites = psMalloc(ssl->hsPool, - cipherSpecsLen * sizeof(*ssl->tls13ClientCipherSuites)); - if (ssl->tls13ClientCipherSuites == NULL) + + /* + Save the supplied cipher suite set. It is needed in case + ClientHello needs to be resent because of HelloRetryRequest. + Skip the backup if already in the middle of a HRR handshake. + */ + if (!ssl->tls13IncorrectDheKeyShare || + ssl->tls13ClientCipherSuitesLen == 0) { - psTraceErrr("Out of mem in tls13WriteClientHello\n"); - goto out_internal_error; + ssl->tls13ClientCipherSuitesLen = 0; + ssl->tls13ClientCipherSuites = psMalloc(ssl->hsPool, + cipherSpecsLen * sizeof(*ssl->tls13ClientCipherSuites)); + if (ssl->tls13ClientCipherSuites == NULL) + { + psTraceErrr("Out of mem in tls13WriteClientHello\n"); + goto out_internal_error; + } + for (i = 0; i < cipherSpecsLen; i++) + { + ssl->tls13ClientCipherSuites[i] = cipherSpecs[i]; + ssl->tls13ClientCipherSuitesLen++; + } } + for (i = 0; i < cipherSpecsLen; i++) { psDynBufAppendAsBigEndianUint16(&ciphersBuf, cipherSpecs[i]); - - /* Save the supplied cipher suite set. It is needed in case - * ClientHello needs to be resent because of HelloRetryRequest */ - ssl->tls13ClientCipherSuites[i] = cipherSpecs[i]; - ssl->tls13ClientCipherSuitesLen++; } psTracePrintCipherList(INDENT_HS_MSG, "cipher_suites", diff --git a/matrixssl/tls13EncodeExt.c b/matrixssl/tls13EncodeExt.c index f0e2f5a..39653d5 100644 --- a/matrixssl/tls13EncodeExt.c +++ b/matrixssl/tls13EncodeExt.c @@ -326,6 +326,12 @@ int32_t tls13WriteSigAlgs(ssl_t *ssl, goto out_internal_error; } + psTracePrintTls13SigAlgList(INDENT_EXTENSION, + "signature_algorithms", + sigAlgs, + sigAlgsLen, + PS_TRUE); + extType[0] = 0; extType[1] = extensionType; @@ -745,6 +751,9 @@ int32_t tls13WritePskIdentity(ssl_t *ssl, { psDynBufAppendOctets(pskBuf, zero, 4); } + + ssl->sec.tls13DidEncodePsk = PS_TRUE; + return PS_SUCCESS; } @@ -897,7 +906,7 @@ int32_t tls13WritePreSharedKey(ssl_t *ssl, }; } PreSharedKeyExtension; */ - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { psDynBufAppendAsBigEndianUint16(&pskBuf, ssl->sec.tls13SelectedIdentityIndex); @@ -992,7 +1001,7 @@ int32_t tls13WriteCookie(ssl_t *ssl, psDynBufAppendOctets(extBuf, extensionType, 2); psDynBufInit(ssl->hsPool, &cookieBuf, 48); - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { psAssert(isHelloRetryRequest); @@ -1036,7 +1045,7 @@ int32_t tls13WriteCookie(ssl_t *ssl, extensionDataLen); # ifdef DEBUG_TLS_1_3_ENCODE_EXTENSIONS - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { psTraceBytes("Encoded HelloRetryRequest.cookie", cookie, @@ -1264,7 +1273,7 @@ int32_t tls13WriteOCSPStatusRequest(ssl_t *ssl, psDynBufAppendOctets(extBuf, extensionType, 2); - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { # ifdef USE_SERVER_SIDE_SSL /* Server sends the stored OCSPResponse. */ diff --git a/matrixssl/tls13KeyAgree.c b/matrixssl/tls13KeyAgree.c index 197976a..2323429 100644 --- a/matrixssl/tls13KeyAgree.c +++ b/matrixssl/tls13KeyAgree.c @@ -685,7 +685,7 @@ int32_t tls13GenerateEphemeralKeys(ssl_t *ssl) uint16_t group; int32_t rc; - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { group = ssl->tls13NegotiatedGroup; rc = tls13GenerateKeyForGroup(ssl, group); diff --git a/matrixssl/tls13KeySchedule.c b/matrixssl/tls13KeySchedule.c index 439a650..691c95e 100644 --- a/matrixssl/tls13KeySchedule.c +++ b/matrixssl/tls13KeySchedule.c @@ -159,10 +159,19 @@ int32_t tls13GenerateEarlySecret(ssl_t *ssl, psSize_t earlySecretLen; int32_t rc; + /* + Do not regenerate the secret if we are in the middle of flight + re-encoding after output buffer resizing. However, we do need to + regenerate if we tried to use a PSK (and thus bootstrapped + our key schedule with it), but ended up not with a non-PSK + handshake. + */ if (ssl->sec.tls13KsState.generateEarlySecretDone) { - /* Already generated. Re-entry? */ - return PS_SUCCESS; + if (!ssl->sec.tls13DidEncodePsk || ssl->sec.tls13UsingPsk) + { + return PS_SUCCESS; + } } /* diff --git a/matrixssl/tls13Psk.c b/matrixssl/tls13Psk.c index 77840c6..6a5ad45 100644 --- a/matrixssl/tls13Psk.c +++ b/matrixssl/tls13Psk.c @@ -263,9 +263,9 @@ int32_t tls13FindSessionPsk(ssl_t *ssl, length and the contents of the first 16 bytes. In the resumption case, the first 16 bytes should be opaque key_name[16]. */ - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { -# ifdef USE_SERVER_SIDE_SSL +# if defined(USE_SERVER_SIDE_SSL) && defined(USE_STATELESS_SESSION_TICKETS) psSessionTicketKeys_t *key; if (idLen >= 16 + 12 + 16) diff --git a/matrixssl/tls13SigVer.c b/matrixssl/tls13SigVer.c index 622267b..ef565a2 100644 --- a/matrixssl/tls13SigVer.c +++ b/matrixssl/tls13SigVer.c @@ -75,7 +75,7 @@ uint16_t tls13ChooseSigAlg(ssl_t *ssl, { psTraceIntInfo("Unsupported pubkey algorithm in our cert: %d\n", pubKeyAlg); - return PS_UNSUPPORTED_FAIL; + return 0; } # else /* If not having USE_CERT_PARSE, we'll need to have just one @@ -153,7 +153,7 @@ uint16_t tls13ChooseSigAlg(ssl_t *ssl, { psTraceInfo("tls13ChooseSigAlg: Priv key does not match " \ "the type of public key in cert\n"); - return PS_UNSUPPORTED_FAIL; + return 0; } # else /* We can do PSS with RSAE, but not the otherway around, so @@ -201,7 +201,7 @@ uint16_t tls13ChooseSigAlg(ssl_t *ssl, /* or try the next key */ } psTraceErrr("Unable to negotiate signature algorithm\n"); - return PS_FAILURE; + return 0; } static int32_t tls13MakeTbs(psPool_t *pool, @@ -426,58 +426,52 @@ int32_t tls13Verify(psPool_t *pool, /* Translate TLS 1.3 signature algorithm encoding to what our crypto layer uses. */ -# ifdef USE_ECC - if (sigAlg == sigalg_ecdsa_secp256r1_sha256) + switch (sigAlg) { +# ifdef USE_ECC + case sigalg_ecdsa_secp256r1_sha256: cryptoLayerSigAlg = OID_SHA256_ECDSA_SIG; psAssert(pubKey->key.ecc.curve->curveId == IANA_SECP256R1); - } - else if (sigAlg == sigalg_ecdsa_secp384r1_sha384) - { + break; + case sigalg_ecdsa_secp384r1_sha384: cryptoLayerSigAlg = OID_SHA384_ECDSA_SIG; psAssert(pubKey->key.ecc.curve->curveId == IANA_SECP384R1); - } - else if (sigAlg == sigalg_ecdsa_secp521r1_sha512) - { + break; + case sigalg_ecdsa_secp521r1_sha512: cryptoLayerSigAlg = OID_SHA512_ECDSA_SIG; psAssert(pubKey->key.ecc.curve->curveId == IANA_SECP521R1); - } + break; # endif # ifdef USE_RSA - else if (sigAlg == sigalg_rsa_pss_pss_sha256 || - sigAlg == sigalg_rsa_pss_rsae_sha256) - { + case sigalg_rsa_pss_pss_sha256: + case sigalg_rsa_pss_rsae_sha256: cryptoLayerSigAlg = OID_SHA256_RSA_SIG; opts.rsaPssHashAlg = PKCS1_SHA256_ID; opts.rsaPssSaltLen = SHA256_HASH_SIZE; opts.useRsaPss = PS_TRUE; - } - else if (sigAlg == sigalg_rsa_pss_pss_sha384 || - sigAlg == sigalg_rsa_pss_rsae_sha384) - { + break; + case sigalg_rsa_pss_pss_sha384: + case sigalg_rsa_pss_rsae_sha384: cryptoLayerSigAlg = OID_SHA384_RSA_SIG; opts.rsaPssHashAlg = PKCS1_SHA384_ID; opts.rsaPssSaltLen = SHA384_HASH_SIZE; opts.useRsaPss = PS_TRUE; - } - else if (sigAlg == sigalg_rsa_pss_pss_sha512 || - sigAlg == sigalg_rsa_pss_rsae_sha512) - { + break; + case sigalg_rsa_pss_pss_sha512: + case sigalg_rsa_pss_rsae_sha512: cryptoLayerSigAlg = OID_SHA512_RSA_SIG; opts.rsaPssHashAlg = PKCS1_SHA512_ID; opts.rsaPssSaltLen = SHA512_HASH_SIZE; opts.useRsaPss = PS_TRUE; - } + break; # endif #ifdef USE_ED25519 - else if (sigAlg == sigalg_ed25519) - { + case sigalg_ed25519: cryptoLayerSigAlg = OID_ED25519_KEY_ALG; psAssert(pubKey->type == PS_ED25519); - } + break; #endif - else - { + default: psTraceIntInfo("Unsupported sig alg in tls13Verify: %u\n", sigAlg); psFree(tbs, pool); @@ -580,6 +574,10 @@ psBool_t tls13RequiresPreHash(uint16_t alg) # ifdef USE_RSA else if (tls13IsRsaPssSigAlg(alg)) { +# ifdef USE_ROT_RSA + /* crypto-rot does not support pre-hash currently. */ + return PS_FALSE; +# endif # ifdef USE_CL_RSA /* Crypto-cl cannot sign pre-hashed data with PSS. So we shall sign the original message instead. */ @@ -591,6 +589,10 @@ psBool_t tls13RequiresPreHash(uint16_t alg) # endif /* USE_RSA */ else { +# ifdef USE_ROT_ECC + /* crypto-rot does not support pre-hash currently. */ + return PS_FALSE; +# endif return PS_TRUE; } } diff --git a/matrixssl/tls13TrHash.c b/matrixssl/tls13TrHash.c index 3671bf5..3206ebd 100644 --- a/matrixssl/tls13TrHash.c +++ b/matrixssl/tls13TrHash.c @@ -33,6 +33,8 @@ #include "matrixsslImpl.h" +# ifndef USE_BUFFERED_HS_HASH + # ifdef USE_TLS_1_3 # ifndef DEBUG_TLS_1_3_TRANSCRIPT_HASH @@ -174,7 +176,7 @@ int32_t tls13TranscriptHashUpdate(ssl_t *ssl, In case of server we originally parse ClientHello in the 1.2 side and later move to 1.3. That's why the hash functions call each other both ways */ - if (!NGTD_VER(ssl, v_tls_1_3_any) && !IS_SERVER(ssl)) + if (!NGTD_VER(ssl, v_tls_1_3_any) && !MATRIX_IS_SERVER(ssl)) { sslUpdateHSHash(ssl, in, len); } @@ -294,3 +296,5 @@ int32_t tls13TranscriptHashSnapshot(ssl_t *ssl, } # endif /* USE_TLS_1_3 */ + +# endif /* USE_BUFFERED_HS_HASH */ diff --git a/matrixssl/tls13TrHashBuffered.c b/matrixssl/tls13TrHashBuffered.c new file mode 100644 index 0000000..a208e57 --- /dev/null +++ b/matrixssl/tls13TrHashBuffered.c @@ -0,0 +1,205 @@ +/** + * @file tls13TrHashBuffered.c + * @version $Format:%h%d$ + * + * TLS 1.3 Transcript-Hash, also called session hash or handshake hash. + * Buffered implementation. + */ +/* + * Copyright (c) 2018 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; 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. + * + * This General Public License does NOT permit incorporating this software + * into proprietary programs. If you are unable to comply with the GPL, a + * commercial license for this software may be purchased from INSIDE at + * http://www.insidesecure.com/ + * + * This program is distributed in 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "matrixsslImpl.h" + +#ifdef USE_BUFFERED_HS_HASH + +# ifdef USE_TLS_1_3 + +# ifndef DEBUG_TLS_1_3_TRANSCRIPT_HASH +# define DEBUG_TLS_1_3_TRANSCRIPT_HASH +# endif + +static inline int32_t getHashAlg(ssl_t *ssl) +{ + /* Only supporting the ciphersuites defined in the TLS 1.3 draft spec. + Only SHA-256 and SHA-384. */ + if (ssl->cipher == NULL) + { + return OID_SHA256_ALG; + } + + if (ssl->cipher->flags & CRYPTO_FLAGS_SHA3) + { + return OID_SHA384_ALG; + } + else + { + return OID_SHA256_ALG; + } +} + +int32_t tls13TranscriptHashInit(ssl_t *ssl) +{ + if (ssl->hsMsgBuf.start == NULL) + { +# ifdef DEBUG_TLS_1_3_TRANSCRIPT_HASH + psTraceInfo("tls13TranscriptHashInit\n"); +# endif + return sslInitHSHash(ssl); + } + return 0; +} + +int32_t tls13TranscriptHashReinit(ssl_t *ssl) +{ + int32_t rc; + int32_t alg; + unsigned char messageHash[1 + 3 + MAX_TLS_1_3_HASH_SIZE]; + psSize_t messageHashLen; + + alg = getHashAlg(ssl); + + psTraceInfo("tls13TranscriptHashReinit\n"); + + /* + When the server responds to a + ClientHello with a HelloRetryRequest, the value of ClientHello1 is + replaced with a special synthetic handshake message of handshake type + "message_hash" containing Hash(ClientHello1). I.e., + + Transcript-Hash(ClientHello1, HelloRetryRequest, ... MN) = + Hash(message_hash || // Handshake type + 00 00 Hash.length || // Handshake message length (bytes) + Hash(ClientHello1) || // Hash of ClientHello1 + HelloRetryRequest ... MN) + */ + rc = tls13TranscriptHashFinish(ssl, ssl->sec.tls13TrHashSnapshotCH1); + if (rc < 0) + { + return rc; + } + rc = tls13TranscriptHashInit(ssl); + if (rc < 0) + { + return rc; + } + + messageHashLen = 4; /* Header. */ + messageHash[0] = 254; + messageHash[1] = messageHash[2] = 0; + if (alg == OID_SHA256_ALG) + { + messageHash[3] = SHA256_HASH_SIZE; + Memcpy(messageHash + 4, + ssl->sec.tls13TrHashSnapshotCH1, + SHA256_HASH_SIZE); + messageHashLen += SHA256_HASH_SIZE; + } + else + { + messageHash[3] = SHA384_HASH_SIZE; + Memcpy(messageHash + 4, + ssl->sec.tls13TrHashSnapshotCH1, + SHA384_HASH_SIZE); + messageHashLen += SHA384_HASH_SIZE; + } + + rc = tls13TranscriptHashUpdate(ssl, + messageHash, + messageHashLen); + if (rc < 0) + { + return rc; + } + + /* Caller should now call update for HelloRetryRequest. */ + + return MATRIXSSL_SUCCESS; +} + +int32_t tls13TranscriptHashUpdate(ssl_t *ssl, + const unsigned char *in, + psSize_t len) +{ +# ifdef DEBUG_TLS_1_3_TRANSCRIPT_HASH + int32_t alg = getHashAlg(ssl); + + psTracePrintTranscriptHashUpdate(ssl, in, len, alg); +# endif + + return sslUpdateHSHash(ssl, in, len); +} + +int32_t tls13TranscriptHashFinish(ssl_t *ssl, + unsigned char *out) +{ + int32_t rc; + +# ifdef DEBUG_TLS_1_3_TRANSCRIPT_HASH + psTraceInfo("tls13TranscriptHashFinish\n"); +# endif + + rc = sslSnapshotHSHash( + ssl, + out, + PS_FALSE, + PS_FALSE); + if (rc < 0) + { + return rc; + } + + /**/ + sslFreeHSHash(ssl); + return 0; +} + +int32_t tls13TranscriptHashSnapshotAlg(ssl_t *ssl, + int32_t alg, + unsigned char *out) +{ + return sslSnapshotHSHash( + ssl, + out, + PS_FALSE, + PS_FALSE); +} + +int32_t tls13TranscriptHashSnapshot(ssl_t *ssl, + unsigned char *out) +{ + int32_t alg = getHashAlg(ssl); + +# ifdef DEBUG_TLS_1_3_TRANSCRIPT_HASH + psTraceInfo("tls13TranscriptHashSnapshot\n"); +# endif + + return tls13TranscriptHashSnapshotAlg(ssl, alg, out); +} + +# endif /* USE_TLS_1_3 */ + +# endif /* USE_BUFFERED_HS_HASH */ diff --git a/matrixssl/tlsDefaults.c b/matrixssl/tlsDefaults.c index 2fdb969..67ac905 100644 --- a/matrixssl/tlsDefaults.c +++ b/matrixssl/tlsDefaults.c @@ -53,32 +53,28 @@ sigalg_ecdsa_secp256r1_sha256 (0x0403) means sha256_ecdsa in TLS 1.2 (TLS 1.2 does not specify the curve to use.) */ -static const uint16_t tls12SigAlgs[] = { - +static const uint16_t tls12SigAlgs[] = +{ sigalg_rsa_pkcs1_sha256, sigalg_rsa_pkcs1_sha384, sigalg_rsa_pkcs1_sha512, sigalg_ecdsa_secp256r1_sha256, sigalg_ecdsa_secp384r1_sha384, sigalg_ecdsa_secp521r1_sha512, -#if 0 - /* this this is a lie - code to verify such signature; fails on client side SKE decode that can't handle - PSS. */ + sigalg_rsa_pkcs1_sha1, + sigalg_ecdsa_sha1, +# ifdef USE_PKCS1_PSS sigalg_rsa_pss_rsae_sha256, sigalg_rsa_pss_rsae_sha384, sigalg_rsa_pss_rsae_sha512, - sigalg_rsa_pss_pss_sha256, - sigalg_rsa_pss_pss_sha384, - sigalg_rsa_pss_pss_sha512, -#endif - sigalg_rsa_pkcs1_sha1, - sigalg_ecdsa_sha1, +# endif 0 }; /* TLS1.3 uses separate lists for certificates and CertificateVerify. This list is for the TLS1.3 SIGNATURE_ALGORITHMS. */ -static const uint16_t tls13SigAlgs[] = { +static const uint16_t tls13SigAlgs[] = +{ sigalg_ecdsa_secp256r1_sha256, sigalg_ecdsa_secp384r1_sha384, sigalg_ecdsa_secp521r1_sha512, @@ -96,7 +92,8 @@ static const uint16_t tls13SigAlgs[] = { /* This list is used for TLS1.3 SIGNATURE_ALGORITHMS_CERT and case where both TLS1.2 and TLS1.3 are enabled */ -static const uint16_t allSigAlgs[] = { +static const uint16_t allSigAlgs[] = +{ sigalg_rsa_pkcs1_sha256, sigalg_rsa_pkcs1_sha384, sigalg_rsa_pkcs1_sha512, @@ -106,12 +103,14 @@ static const uint16_t allSigAlgs[] = { # ifdef USE_ED25519 sigalg_ed25519, # endif +# ifdef USE_PKCS1_PSS sigalg_rsa_pss_rsae_sha256, sigalg_rsa_pss_rsae_sha384, sigalg_rsa_pss_rsae_sha512, sigalg_rsa_pss_pss_sha256, sigalg_rsa_pss_pss_sha384, sigalg_rsa_pss_pss_sha512, +# endif sigalg_rsa_pkcs1_sha1, sigalg_ecdsa_sha1, 0 diff --git a/matrixssl/tlsSelectKeys.c b/matrixssl/tlsSelectKeys.c index 2e4d6a8..06c7bfd 100644 --- a/matrixssl/tlsSelectKeys.c +++ b/matrixssl/tlsSelectKeys.c @@ -66,12 +66,43 @@ const sslKeySelectInfo_t *matrixSslGetClientKeySelectInfo(ssl_t *ssl) return &ssl->sec.keySelect; } +static +int32_t checkSigAlg(ssl_t *ssl, + sslKeySelectInfo_t *keySelect, + uint32_t certSigAlg) +{ + uint32_t check = 0; + + if (USING_TLS_1_3(ssl)) + { + check = keySelect->peerCertSigAlgMask; + } + else + { + check = keySelect->peerSigAlgMask; + } + + if (check != 0 && !peerSupportsSigAlg(certSigAlg, check)) + { +# ifdef DEBUG_TLS_SELECT_KEYS + psTraceIntInfo("identityCb: invalid cert sig algorithm %x ", + cert->sigAlgorithm); + psTraceIntInfo("Not found in list: %x\n", check); +# endif /* DEBUG_TLS_SELECT_KEYS */ + return PS_FAILURE; + } + + return PS_SUCCESS; +} + /* Choose a client cert and key from the ssl->keys->identity list. */ static int32_t chooseFromLoadedKeys(ssl_t *ssl, sslKeySelectInfo_t *keySelect) { - psBool_t found; + psBool_t found = PS_FALSE; int i; + int32_t rc; + sslIdentity_t *id; /* RFC 5246, section 7.4.4: "Any certificates provided by the client MUST be signed using a hash/signature algorithm pair @@ -80,76 +111,83 @@ int32_t chooseFromLoadedKeys(ssl_t *ssl, sslKeySelectInfo_t *keySelect) cert is found. */ if (keySelect->nCas == 0) { - /* server did not specify CA's. Use the first key */ - ssl->chosenIdentity = ssl->keys->identity; -# ifdef USE_CLIENT_SIDE_SSL - ssl->sec.certMatch = 1; -# endif - psTraceInfo("no CA's from peer: using first given\n"); - } - - for (found = PS_FALSE, i = 0; !found && i < keySelect->nCas; i++) - { -# ifdef USE_CERT_PARSE - sslIdentity_t *has; - psX509Cert_t *cert; - - for (has = ssl->keys->identity; !found && has; has = has->next) + /* + Server did not specify CA's. Use the first key that can + is compatible with the server's supported_signature_algorithms. + */ + id = ssl->keys->identity; + do { - /* traverse up chains to find accepted issuer */ - for (cert = has->cert; cert; cert = cert->next) + rc = checkSigAlg(ssl, + keySelect, + id->cert->sigAlgorithm); + if (rc == PS_SUCCESS) { - if (cert->issuer.dnencLen == keySelect->caNameLens[i] - && Memcmp(cert->issuer.dnenc, - keySelect->caNames[i], - keySelect->caNameLens[i]) == 0) - { - uint32_t check = 0; + ssl->chosenIdentity = id; +# ifdef USE_CLIENT_SIDE_SSL + ssl->sec.certMatch = 1; +# endif + found = PS_TRUE; + break; + } + id = id->next; + } + while (id != NULL); + } + else + { + for (found = PS_FALSE, i = 0; !found && i < keySelect->nCas; i++) + { +# ifdef USE_CERT_PARSE + sslIdentity_t *has; + psX509Cert_t *cert; - if (USING_TLS_1_3(ssl)) + for (has = ssl->keys->identity; !found && has; has = has->next) + { + /* traverse up chains to find accepted issuer */ + for (cert = has->cert; cert; cert = cert->next) + { + if (cert->issuer.dnencLen == keySelect->caNameLens[i] + && Memcmp(cert->issuer.dnenc, + keySelect->caNames[i], + keySelect->caNameLens[i]) == 0) { - check = keySelect->peerCertSigAlgMask; + rc = checkSigAlg(ssl, + keySelect, + cert->sigAlgorithm); + if (rc != PS_SUCCESS) + { + continue; + } + + /* This chain was found to be fruitful - + issuer is withing the path, and algorithms + are fine. */ + ssl->chosenIdentity = has; +# ifdef USE_CLIENT_SIDE_SSL + ssl->sec.certMatch = 1; +# endif + found = PS_TRUE; + break; } else { - check = keySelect->peerSigAlgMask; - } - - if (check != 0 && !peerSupportsSigAlg(cert->sigAlgorithm, check)) - { # ifdef DEBUG_TLS_SELECT_KEYS - psTraceIntInfo("identityCb: invalid cert sig algorithm %x ", - cert->sigAlgorithm); - psTraceIntInfo("Not found in list: %x\n", check); + psTraceInfo("identityCb: issuer name mismatch\n"); + psTraceBytes("has: ", + (const unsigned char*)cert->issuer.dnenc, + cert->issuer.dnencLen); + psTraceBytes("req: ", + keySelect->caNames[i], + keySelect->caNameLens[i]); # endif /* DEBUG_TLS_SELECT_KEYS */ - continue; } - - /* This chain was found to be fruitful - - issuer is withing the path, and algorithms are fine. */ - ssl->chosenIdentity = has; -# ifdef USE_CLIENT_SIDE_SSL - ssl->sec.certMatch = 1; -# endif - found = PS_TRUE; - break; - } - else - { -# ifdef DEBUG_TLS_SELECT_KEYS - psTraceInfo("identityCb: issuer name mismatch\n"); - psTraceBytes("has: ", - (const unsigned char*)cert->issuer.dnenc, - cert->issuer.dnencLen); - psTraceBytes("req: ", - keySelect->caNames[i], - keySelect->caNameLens[i]); -# endif /* DEBUG_TLS_SELECT_KEYS */ } } - } #endif /* USE_CERT_PARSE */ + } } + if (ssl->chosenIdentity == NULL) { psTraceInfo("identityCb: no keys matched\n"); @@ -165,6 +203,8 @@ int32_t chooseFromLoadedKeys(ssl_t *ssl, sslKeySelectInfo_t *keySelect) if (found) { psAssert(ssl->chosenIdentity != NULL); + psTraceInfo("Chosen client auth key:\n "); + psTracePrintPubKeyTypeAndSize(ssl, &ssl->chosenIdentity->privKey); return PS_SUCCESS; } return PS_FAILURE; diff --git a/matrixssl/tlsSigVer.c b/matrixssl/tlsSigVer.c index 501d428..1cafb7e 100644 --- a/matrixssl/tlsSigVer.c +++ b/matrixssl/tlsSigVer.c @@ -37,6 +37,14 @@ # ifndef USE_ONLY_PSK_CIPHER_SUITE +# ifdef USE_ROT_CRYPTO +# include "../crypto-rot/rotCommon.h" +# endif + +# ifndef DEBUG_TLS_SIG_VER +/*# define DEBUG_TLS_SIG_VER*/ +# endif + uint32_t getDefaultSkeHashSize(ssl_t *ssl) { uint32_t hashSize; @@ -74,66 +82,66 @@ int32_t computeSkeHash(ssl_t *ssl, { # ifdef USE_MD5SHA1 case MD5SHA1_HASH_SIZE: - psMd5Sha1PreInit(&digestCtx->md5sha1); - psMd5Sha1Init(&digestCtx->md5sha1); - psMd5Sha1Update(&digestCtx->md5sha1, ssl->sec.clientRandom, + psMd5Sha1PreInit(&digestCtx->u.md5sha1); + psMd5Sha1Init(&digestCtx->u.md5sha1); + psMd5Sha1Update(&digestCtx->u.md5sha1, ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE); - psMd5Sha1Update(&digestCtx->md5sha1, ssl->sec.serverRandom, + psMd5Sha1Update(&digestCtx->u.md5sha1, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE); - psMd5Sha1Update(&digestCtx->md5sha1, tbsStart, + psMd5Sha1Update(&digestCtx->u.md5sha1, tbsStart, (uint32) (tbsStop - tbsStart)); - psMd5Sha1Final(&digestCtx->md5sha1, hsMsgHash); + psMd5Sha1Final(&digestCtx->u.md5sha1, hsMsgHash); break; # endif /* USE_MD5SHA1 */ # ifdef USE_SHA1 case SHA1_HASH_SIZE: - psSha1PreInit(&digestCtx->sha1); - psSha1Init(&digestCtx->sha1); - psSha1Update(&digestCtx->sha1, ssl->sec.clientRandom, + psSha1PreInit(&digestCtx->u.sha1); + psSha1Init(&digestCtx->u.sha1); + psSha1Update(&digestCtx->u.sha1, ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE); - psSha1Update(&digestCtx->sha1, ssl->sec.serverRandom, + psSha1Update(&digestCtx->u.sha1, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE); - psSha1Update(&digestCtx->sha1, tbsStart, + psSha1Update(&digestCtx->u.sha1, tbsStart, (uint32) (tbsStop - tbsStart)); - psSha1Final(&digestCtx->sha1, hsMsgHash); + psSha1Final(&digestCtx->u.sha1, hsMsgHash); break; # endif /* USE_SHA1 */ # ifdef USE_TLS_1_2 case SHA256_HASH_SIZE: - psSha256PreInit(&digestCtx->sha256); - psSha256Init(&digestCtx->sha256); - psSha256Update(&digestCtx->sha256, ssl->sec.clientRandom, + psSha256PreInit(&digestCtx->u.sha256); + psSha256Init(&digestCtx->u.sha256); + psSha256Update(&digestCtx->u.sha256, ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE); - psSha256Update(&digestCtx->sha256, ssl->sec.serverRandom, + psSha256Update(&digestCtx->u.sha256, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE); - psSha256Update(&digestCtx->sha256, tbsStart, + psSha256Update(&digestCtx->u.sha256, tbsStart, (uint32) (tbsStop - tbsStart)); - psSha256Final(&digestCtx->sha256, hsMsgHash); + psSha256Final(&digestCtx->u.sha256, hsMsgHash); break; # ifdef USE_SHA384 case SHA384_HASH_SIZE: - psSha384PreInit(&digestCtx->sha384); - psSha384Init(&digestCtx->sha384); - psSha384Update(&digestCtx->sha384, ssl->sec.clientRandom, + psSha384PreInit(&digestCtx->u.sha384); + psSha384Init(&digestCtx->u.sha384); + psSha384Update(&digestCtx->u.sha384, ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE); - psSha384Update(&digestCtx->sha384, ssl->sec.serverRandom, + psSha384Update(&digestCtx->u.sha384, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE); - psSha384Update(&digestCtx->sha384, tbsStart, + psSha384Update(&digestCtx->u.sha384, tbsStart, (uint32) (tbsStop - tbsStart)); - psSha384Final(&digestCtx->sha384, hsMsgHash); + psSha384Final(&digestCtx->u.sha384, hsMsgHash); break; # endif /* USE_SHA384 */ # ifdef USE_SHA512 case SHA512_HASH_SIZE: - psSha512PreInit(&digestCtx->sha512); - psSha512Init(&digestCtx->sha512); - psSha512Update(&digestCtx->sha512, ssl->sec.clientRandom, + psSha512PreInit(&digestCtx->u.sha512); + psSha512Init(&digestCtx->u.sha512); + psSha512Update(&digestCtx->u.sha512, ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE); - psSha512Update(&digestCtx->sha512, ssl->sec.serverRandom, + psSha512Update(&digestCtx->u.sha512, ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE); - psSha512Update(&digestCtx->sha512, tbsStart, + psSha512Update(&digestCtx->u.sha512, tbsStart, (uint32) (tbsStop - tbsStart)); - psSha512Final(&digestCtx->sha512, hsMsgHash); + psSha512Final(&digestCtx->u.sha512, hsMsgHash); break; # endif /* USE_SHA512 */ # endif /* USE_TLS_1_2 */ @@ -146,6 +154,41 @@ int32_t computeSkeHash(ssl_t *ssl, return PS_SUCCESS; } +psRes_t computeSkeTbs(ssl_t *ssl, + const unsigned char *tbsStart, + const unsigned char *tbsStop, + unsigned char **out, + psSizeL_t *outLen) +{ + unsigned char *tbs; + psSize_t tbsLen; + + /* + TBS length is 2x32 bytes for client_random || server_random + plus the size of signed_params. + */ + tbsLen = 64 + (tbsStop - tbsStart); + tbs = psMalloc(ssl->hsPool, tbsLen); + if (tbs == NULL) + { + return PS_MEM_FAIL; + } + + Memcpy(tbs, ssl->sec.clientRandom, 32); + Memcpy(tbs + 32, ssl->sec.serverRandom, 32); + Memcpy(tbs + 64, tbsStart, tbsStop - tbsStart); + +# ifdef DEBUG_TLS_SIG_VER + psTraceBytes("computeSkeTbs", tbs, tbsLen); +# endif + + *out = tbs; + *outLen = tbsLen; + + return PS_SUCCESS; +} + +# ifdef USE_IDENTITY_CERTIFICATES static inline int32_t chooseSkeSigAlgTls12(ssl_t *ssl, sslIdentity_t *id) { @@ -194,12 +237,16 @@ int32_t chooseSkeSigAlg(ssl_t *ssl, sslIdentity_t *id) psRes_t tlsPrepareSkeSignature(ssl_t *ssl, int32_t skeSigAlg, unsigned char *tbsStart, - unsigned char *c) + unsigned char *c, + psBool_t needPreHash) { sslIdentity_t *chosen = ssl->chosenIdentity; unsigned char *orig = c; psDigestContext_t digestCtx; - unsigned char *hsMsgHash, *tbsStop; + unsigned char *hsMsgHash = NULL; + unsigned char *tbs = NULL; + psSizeL_t tbsLen = 0; + unsigned char *tbsStop; int32_t rc; void *pkiData = ssl->userPtr; pkaAfter_t *pkaAfter; @@ -228,13 +275,6 @@ psRes_t tlsPrepareSkeSignature(ssl_t *ssl, /* [tbsStart, tbsStop] == signed_params. */ tbsStop = c; - /* Reserve space for the hash of signed_params. */ - hsMsgHash = psMalloc(ssl->hsPool, SHA512_HASH_SIZE); - if (hsMsgHash == NULL) - { - return PS_MEM_FAIL; - } - hashSize = getDefaultSkeHashSize(ssl); # ifdef USE_TLS_1_2 @@ -246,7 +286,6 @@ psRes_t tlsPrepareSkeSignature(ssl_t *ssl, &hashSize); if (rc < 0) { - psFree(hsMsgHash, ssl->hsPool); return rc; } *c++ = sigAlgId[0]; @@ -254,17 +293,41 @@ psRes_t tlsPrepareSkeSignature(ssl_t *ssl, } # endif - /* Compute the hash. */ - rc = computeSkeHash(ssl, - &digestCtx, - hashSize, - tbsStart, - tbsStop, - hsMsgHash); - if (rc < 0) + if (needPreHash) { - psFree(hsMsgHash, ssl->hsPool); - return rc; + /* Reserve space for the hash of signed_params. */ + hsMsgHash = psMalloc(ssl->hsPool, SHA512_HASH_SIZE); + if (hsMsgHash == NULL) + { + return PS_MEM_FAIL; + } + + /* Compute the hash. */ + rc = computeSkeHash(ssl, + &digestCtx, + hashSize, + tbsStart, + tbsStop, + hsMsgHash); + if (rc < 0) + { + psFree(hsMsgHash, ssl->hsPool); + return rc; + } + } + else + { + /* No pre-hash, but need to provide the TBS as a contiguous + buffer for later hashing and signing. */ + rc = computeSkeTbs(ssl, + tbsStart, + tbsStop, + &tbs, + &tbsLen); + if (rc < 0) + { + return rc; + } } /* Compute the signature lengths and write the signature length @@ -312,6 +375,10 @@ psRes_t tlsPrepareSkeSignature(ssl_t *ssl, psFree(hsMsgHash, ssl->hsPool); Memcpy(c, ssl->ckeMsg, ssl->ckeSize); c += ssl->ckeSize; + if (tbs != NULL) + { + psFree(tbs, ssl->hsPool); + } return (c - orig); } # endif /* USE_DTLS */ @@ -319,14 +386,26 @@ psRes_t tlsPrepareSkeSignature(ssl_t *ssl, pkaAfter = getPkaAfter(ssl); if (pkaAfter == NULL) { - psTraceInfo("getPkaAfter error\n"); + psTraceErrr("getPkaAfter error\n"); psFree(hsMsgHash, ssl->hsPool); + if (tbs != NULL) + { + psFree(tbs, ssl->hsPool); + } return PS_PLATFORM_FAIL; } - pkaAfter->inbuf = hsMsgHash; + if (needPreHash) + { + pkaAfter->inbuf = hsMsgHash; + pkaAfter->inlen = hashSize; + } + else + { + pkaAfter->inbuf = tbs; + pkaAfter->inlen = tbsLen; + } pkaAfter->outbuf = c; pkaAfter->data = pkiData; - pkaAfter->inlen = hashSize; pkaAfter->type = pkaType; /* Advance write pointer by the predicted size of the signature. */ @@ -364,6 +443,7 @@ psRes_t tlsPrepareSkeSignature(ssl_t *ssl, return (c - orig); } + static psPool_t *getTmpPkiPool(ssl_t *ssl, pkaAfter_t *pka) { @@ -379,60 +459,53 @@ psRes_t tlsMakeSkeSignature(ssl_t *ssl, int32_t sigAlg = OID_RSA_TLS_SIG_ALG; sslIdentity_t *chosen = ssl->chosenIdentity; psPubKey_t *privKey = &chosen->privKey; - unsigned char *sigBuf = pka->outbuf; + unsigned char *sigBuf; psSize_t sigLen; psSignOpts_t opts = {0}; - /* New temp location for ECDSA sig which can be one len byte different - than what we originally calculated (pka->user is holding) */ - unsigned char *tmpEcdsa = NULL; - /* Prepare for the call to psSign. */ + /* + Prepare for the call to psSign. + RSA signatures are be generated straight into pka->outbuf. + ECDSA signatures use an intermediate temporary buffer. + + For RSA, the TLS signature vector length octets have been written + in tlsPrepareSkeSignature. With ECDSA, we cannot completely predict + the signature size in advance, so we ask psSign to prepend the + TLS vector length (INCLUDE_SIZE option) to the signature. + */ switch (pka->type) { # ifdef USE_RSA_CIPHER_SUITE case PKA_AFTER_RSA_SIG_GEN_ELEMENT: sigAlg = OID_RSA_PKCS15_SIG_ALG; sigLen = privKey->keysize; + sigBuf = pka->outbuf; + opts.flags |= PS_SIGN_OPTS_USE_PREALLOCATED_OUTBUF; break; - case PKA_AFTER_RSA_SIG_GEN: sigAlg = OID_RSA_TLS_SIG_ALG; sigLen = privKey->keysize; + sigBuf = pka->outbuf; + opts.flags |= PS_SIGN_OPTS_USE_PREALLOCATED_OUTBUF; break; # endif /* USE_RSA_CIPHER_SUITE */ - # ifdef USE_ECC_CIPHER_SUITE case PKA_AFTER_ECDSA_SIG_GEN: sigAlg = OID_ECDSA_TLS_SIG_ALG; - /* pka->user is the predicted ECDSA signature size. We predicted - that one of the INTEGERs has a leading 0x00 octet, but there - may actually be 0 to 2 extra octets. So allocate 1 larger - than predicted. */ - tmpEcdsa = psMalloc(ssl->hsPool, pka->user + 1); - if (tmpEcdsa == NULL) - { - return PS_MEM_FAIL; - } # ifdef USE_DTLS ssl->ecdsaSizeChange = 0; # endif - sigBuf = tmpEcdsa; - /* We did not write the signature vector length octets earlier, - because we cannot completely predict the signature legnth. - Let psSign do this. */ opts.flags |= PS_SIGN_OPTS_ECDSA_INCLUDE_SIZE; break; # endif /* USE_ECC_CIPHER_SUITE */ - default: psTraceErrr("Unsupported type of PKA operation\n"); return PS_UNSUPPORTED_FAIL; } opts.userData = pka->data; - opts.flags |= PS_SIGN_OPTS_USE_PREALLOCATED_OUTBUF; /* Compute the signature. */ - rc = psSignHash(pkiPool, + rc = psSign(pkiPool, privKey, sigAlg, pka->inbuf, @@ -443,24 +516,33 @@ psRes_t tlsMakeSkeSignature(ssl_t *ssl, if (rc == PS_PENDING) { /* Async operation launched, but not complete. */ - /* If the result is going directly inline to the output - buffer we unflag 'type' so this function isn't called - again on the way back around. Also, we can safely - free inbuf because it has been copied out */ - psFree(pka->inbuf, ssl->hsPool); pka->inbuf = NULL; + /* + If the result is going directly inline to the output + buffer we unflag 'type' so this function isn't called + again on the way back around. Also, we can safely + free inbuf because it has been copied out. + */ + psFree(pka->inbuf, ssl->hsPool); + pka->inbuf = NULL; pka->type = 0; - psFree(tmpEcdsa, ssl->hsPool); + if (sigBuf != pka->outbuf) + { + psFree(sigBuf, ssl->pkiPool); + } return rc; } else if (rc < 0) { - psFree(tmpEcdsa, ssl->hsPool); + if (sigBuf != pka->outbuf) + { + psFree(sigBuf, ssl->hsPool); + } psTraceErrr("SKE signature generation failed\n"); psTraceIntInfo("Signature return code: %d\n", rc); return MATRIXSSL_ERROR; } - /* Signature is ready, either in tmpEcdsa or in pka->outbuf. */ + /* Signature is ready, either in sigBuf or in pka->outbuf. */ /* If the signature size is different than predicted, we need to tweak the previously encoded flight to account for this. @@ -477,21 +559,21 @@ psRes_t tlsMakeSkeSignature(ssl_t *ssl, rc = accountForEcdsaSizeChange(ssl, pka, sigLen, - tmpEcdsa, + sigBuf, out, SSL_HS_SERVER_KEY_EXCHANGE); if (rc < 0) { clearPkaAfter(ssl); - psFree(tmpEcdsa, ssl->hsPool); + psFree(sigBuf, ssl->hsPool); return MATRIXSSL_ERROR; } } else { - Memcpy(pka->outbuf, tmpEcdsa, pka->user); + Memcpy(pka->outbuf, sigBuf, pka->user); } - psFree(tmpEcdsa, ssl->hsPool); + psFree(sigBuf, pkiPool); } # endif /* USE_ECC_CIPHER_SUITE */ @@ -506,7 +588,7 @@ psRes_t tlsMakeSkeSignature(ssl_t *ssl, ssl->ckeMsg = psMalloc(ssl->hsPool, ssl->ckeSize); if (ssl->ckeMsg == NULL) { - psTraceInfo("Memory allocation error ckeMsg\n"); + psTraceErrr("Memory allocation error ckeMsg\n"); return PS_MEM_FAIL; } Memcpy(ssl->ckeMsg, pka->outbuf, ssl->ckeSize); @@ -517,6 +599,7 @@ psRes_t tlsMakeSkeSignature(ssl_t *ssl, return rc; } +#endif /* USE_IDENTITY_CERTIFICATES */ psBool_t tlsIsSupportedRsaSigAlg(int32_t alg) { @@ -527,6 +610,11 @@ psBool_t tlsIsSupportedRsaSigAlg(int32_t alg) case sigalg_rsa_pkcs1_sha256: case sigalg_rsa_pkcs1_sha384: case sigalg_rsa_pkcs1_sha512: +# ifdef USE_PKCS1_PSS + case sigalg_rsa_pss_rsae_sha256: + case sigalg_rsa_pss_rsae_sha384: + case sigalg_rsa_pss_rsae_sha512: +# endif return PS_TRUE; default: return PS_FALSE; @@ -550,7 +638,7 @@ psBool_t tlsIsSupportedEcdsaSigAlg(int32_t alg) } } -psSize_t tlsSigAlgToHashLen(uint16_t alg) +psResSize_t tlsSigAlgToHashLen(uint16_t alg) { /* Note: We are in TLS 1.2 context here. The sigalg_* names below are from TLS 1.3, but they are compatible with the TLS 1.2 @@ -563,12 +651,15 @@ psSize_t tlsSigAlgToHashLen(uint16_t alg) case sigalg_ecdsa_sha1: return SHA1_HASH_SIZE; case sigalg_rsa_pkcs1_sha256: + case sigalg_rsa_pss_rsae_sha256: case sigalg_ecdsa_secp256r1_sha256: return SHA256_HASH_SIZE; case sigalg_rsa_pkcs1_sha384: + case sigalg_rsa_pss_rsae_sha384: case sigalg_ecdsa_secp384r1_sha384: return SHA384_HASH_SIZE; case sigalg_rsa_pkcs1_sha512: + case sigalg_rsa_pss_rsae_sha512: case sigalg_ecdsa_secp521r1_sha512: return SHA512_HASH_SIZE; default: @@ -588,6 +679,10 @@ int32_t tlsSigAlgToMatrix(uint16_t alg) return OID_SHA384_RSA_SIG; case sigalg_rsa_pkcs1_sha512: return OID_SHA512_RSA_SIG; + case sigalg_rsa_pss_rsae_sha256: + case sigalg_rsa_pss_rsae_sha384: + case sigalg_rsa_pss_rsae_sha512: + return OID_RSASSA_PSS; case sigalg_ecdsa_sha1: return OID_SHA1_ECDSA_SIG; case sigalg_ecdsa_secp256r1_sha256: @@ -619,7 +714,9 @@ int32_t tlsVerify(ssl_t *ssl, psVerifyOptions_t defaultOpts = {0}; psBool_t verifyResult; const unsigned char *orig_c = c; - psBool_t useRsa = PS_FALSE;; + psBool_t useRsa = PS_FALSE; + unsigned char *refTbs; + psSizeL_t refTbsLen; if (opts == NULL) { @@ -660,6 +757,34 @@ int32_t tlsVerify(ssl_t *ssl, { goto out_decode_error; } +# ifdef USE_PKCS1_PSS + switch (sigAlgTls) + { + case sigalg_rsa_pss_rsae_sha256: + opts->useRsaPss = PS_TRUE; + opts->rsaPssHashAlg = PKCS1_SHA256_ID; + opts->rsaPssSaltLen = SHA256_HASH_SIZE; + break; + case sigalg_rsa_pss_rsae_sha384: + opts->useRsaPss = PS_TRUE; + opts->rsaPssHashAlg = PKCS1_SHA384_ID; + opts->rsaPssSaltLen = SHA384_HASH_SIZE; + break; + case sigalg_rsa_pss_rsae_sha512: + opts->useRsaPss = PS_TRUE; + opts->rsaPssHashAlg = PKCS1_SHA512_ID; + opts->rsaPssSaltLen = SHA512_HASH_SIZE; + break; + } +# ifdef USE_CL_RSA + if (opts->useRsaPss) + { + /* The crypto-cl API for RSA-PSS verification does not support + pre-hashing. */ + opts->noPreHash = PS_TRUE; + } +# endif /* USE_CL_RSA */ +# endif /* USE_PKCS1_PSS */ } # endif /* USE_TLS_1_2 */ @@ -720,21 +845,39 @@ int32_t tlsVerify(ssl_t *ssl, goto out_decode_error; } - /* Now compute the reference hash. */ - - if (hashLen == 0) + if (opts == NULL || opts->noPreHash == PS_FALSE) { - hashLen = getDefaultSkeHashSize(ssl); + /* Compute the reference hash. */ + if (hashLen == 0) + { + hashLen = getDefaultSkeHashSize(ssl); + } + rc = computeSkeHash(ssl, + &digestCtx, + hashLen, + tbs, + tbs + tbsLen, + hashBuf); + if (rc < 0) + { + goto out_illegal_parameter; + } + refTbs = hashBuf; + refTbsLen = hashLen; } - rc = computeSkeHash(ssl, - &digestCtx, - hashLen, - tbs, - tbs + tbsLen, - hashBuf); - if (rc < 0) + else { - goto out_illegal_parameter; + /* No pre-hashing before signature verification. + Construct the reference tbs as a contiguous block. */ + rc = computeSkeTbs(ssl, + tbs, + tbs + tbsLen, + &refTbs, + &refTbsLen); + if (rc < 0) + { + return rc; + } } /* Now verify the signature. */ @@ -753,8 +896,8 @@ int32_t tlsVerify(ssl_t *ssl, } rc = psVerifySig(ssl->hsPool, - hashBuf, - hashLen, + refTbs, + refTbsLen, c, sigLen, pubKey, @@ -764,9 +907,18 @@ int32_t tlsVerify(ssl_t *ssl, if (rc < 0 || verifyResult != PS_TRUE) { psTraceErrr("Can't verify serverKeyExchange sig\n"); + if (refTbs != hashBuf) + { + psFree(refTbs, ssl->hsPool); + } goto out_decrypt_error; } + if (refTbs != hashBuf) + { + psFree(refTbs, ssl->hsPool); + } + c += sigLen; psAssert(c > orig_c); @@ -1146,6 +1298,7 @@ int32_t ecdsaToRsa(int32_t sigAlg) @return The signature algorithm to use. */ int32_t chooseSigAlgInt(int32_t certSigAlg, + psPubKey_t *privKey, psSize_t keySize, int32_t keyAlgorithm, uint16_t peerSigAlgs) @@ -1166,6 +1319,15 @@ int32_t chooseSigAlgInt(int32_t certSigAlg, } #endif +#ifdef USE_ROT_ECC + if (keyAlgorithm == OID_ECDSA_KEY_ALG) + { + psTraceIntInfo("keySize is %hu\n", keySize); + psTraceIntInfo("curve ID is %hu\n", privKey->key.ecc.curve->curveId); + return psRotCurveToSigAlg(privKey->key.ecc.curve->curveId); + } +#endif + /* We are going to use certSigAlg as the basis of our choice. This is because the SSL layer must ensure anyway that the peer @@ -1257,6 +1419,7 @@ int32_t chooseSigAlg(psX509Cert_t *cert, # endif /* USE_CERT_PARSE */ return chooseSigAlgInt(cert->sigAlgorithm, + privKey, privKey->keysize, pubKeyAlg, peerSigAlgs); diff --git a/matrixssl/tlsTrace.c b/matrixssl/tlsTrace.c index 9e72ed1..2d742c3 100644 --- a/matrixssl/tlsTrace.c +++ b/matrixssl/tlsTrace.c @@ -4,8 +4,7 @@ * * Simple logging and tracing functions for TLS. * These functions should be called via the corresponding psTrace* macros - * defined in matrixssllib.h, when USE_SSL_HANDSHAKE_MSG_TRACE and/or - * USE_SSL_USE_SSL_INFORMATIONAL_TRACE is off. + * defined in matrixssllib.h. */ /* * Copyright (c) 2013-2018 INSIDE Secure Corporation @@ -349,7 +348,7 @@ void psPrintAlertReceiveInfo(ssl_t *ssl, unsigned char alertType) void psPrintHsMessageCreate(ssl_t *ssl, unsigned char hsMsgType) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace("<<< Server creating "); } @@ -380,7 +379,7 @@ psBool_t isTls13ClientHello(ssl_t *ssl, unsigned char hsMsgType) { return PS_FALSE; } - if (!IS_SERVER(ssl)) + if (!MATRIX_IS_SERVER(ssl)) { return PS_TRUE; } @@ -389,7 +388,7 @@ psBool_t isTls13ClientHello(ssl_t *ssl, unsigned char hsMsgType) void psPrintHsMessageParse(ssl_t *ssl, unsigned char hsMsgType) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(">>> Server parsing "); } @@ -408,7 +407,7 @@ void psPrintHsMessageParse(ssl_t *ssl, unsigned char hsMsgType) void psPrintChangeCipherSpecParse(ssl_t *ssl) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(">>> Server parsing "); } @@ -421,7 +420,7 @@ void psPrintChangeCipherSpecParse(ssl_t *ssl) void psPrintChangeCipherSpecCreate(ssl_t *ssl) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace("<<< Server creating "); } @@ -443,7 +442,7 @@ void psPrintChangeCipherSpecCreate(ssl_t *ssl) */ void psPrintExtensionParse(ssl_t *ssl, uint16_t extType) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(">>> Server parsing "); } @@ -461,7 +460,7 @@ void psPrintExtensionParse(ssl_t *ssl, uint16_t extType) void psPrintExtensionCreate(ssl_t *ssl, uint16_t extType) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(">>> Server adding "); } @@ -558,6 +557,7 @@ void psPrintSigAlgs(psSize_t indentLevel, void psPrintTls13SigAlg(psSize_t indentLevel, const char *where, uint16_t alg, + psBool_t bigEndian, psBool_t addNewline) { tlsTraceIndent(indentLevel, NULL); @@ -567,6 +567,11 @@ void psPrintTls13SigAlg(psSize_t indentLevel, tlsTraceStr("%s: ", where); } + if (bigEndian) + { + alg = ((alg & 0xff) << 8) | ((alg & 0xff00) >> 8); + } + if (alg == sigalg_rsa_pkcs1_sha256) { tlsTrace("rsa_pkcs1_sha256"); @@ -642,10 +647,12 @@ void psPrintTls13SigAlg(psSize_t indentLevel, } } -void psPrintTls13SigAlgList(psSize_t indentLevel, +static +void psPrintTls13SigAlgListInner(psSize_t indentLevel, const char *where, - uint16_t *algs, + const uint16_t *algs, psSize_t numAlgs, + psBool_t bigEndian, psBool_t addNewline) { psSize_t i; @@ -659,11 +666,43 @@ void psPrintTls13SigAlgList(psSize_t indentLevel, for (i = 0; i < numAlgs; i++) { - psPrintTls13SigAlg(indentLevel, NULL, algs[i], PS_TRUE); + psPrintTls13SigAlg(indentLevel, + NULL, + algs[i], + bigEndian, + PS_TRUE); } tlsTrace("\n"); } +void psPrintTls13SigAlgList(psSize_t indentLevel, + const char *where, + const uint16_t *algs, + psSize_t numAlgs, + psBool_t addNewline) +{ + return psPrintTls13SigAlgListInner(indentLevel, + where, + algs, + numAlgs, + PS_FALSE, + PS_TRUE); +} + +void psPrintTls13SigAlgListBigEndian(psSize_t indentLevel, + const char *where, + const uint16_t *algs, + psSize_t numAlgs, + psBool_t addNewline) +{ + return psPrintTls13SigAlgListInner(indentLevel, + where, + algs, + numAlgs, + PS_TRUE, + PS_TRUE); +} + void psPrintVer(psProtocolVersion_t ver) { tlsTrace(VER_TO_STR(VER_GET_RAW(ver))); @@ -956,6 +995,50 @@ void psPrintTls13NamedGroupList(psSize_t indentLevel, } } +void psPrintEcFlags(psSize_t indentLevel, + const char *where, + uint32_t ecFlags, + ssl_t *ssl, + psBool_t addNewline) +{ + tlsTraceIndent(indentLevel, NULL); + if (where) + { + tlsTraceIndent(indentLevel, NULL); + tlsTraceStr("%s :\n", where); + indentLevel++; + } +# ifdef USE_ECC + if (ecFlags & IS_SECP192R1) + { + tlsTrace("P-192\n"); + } + else if (ecFlags & IS_SECP224R1) + { + tlsTrace("P-224\n"); + } + else if (ecFlags & IS_SECP256R1) + { + tlsTrace("P-256\n"); + } + else if (ecFlags & IS_SECP384R1) + { + tlsTrace("P-384\n"); + } + else if (ecFlags & IS_SECP521R1) + { + tlsTrace("P-521\n"); + } +# else + tlsTrace("Need USE_ECC for this\n"); +# endif + + if (addNewline) + { + tlsTrace("\n"); + } +} + void psPrintTlsKeys(const char *where, ssl_t *ssl, psBool_t addNewline) @@ -1398,7 +1481,7 @@ void psPrintTranscriptHashUpdate(ssl_t *ssl, psSizeL_t inLen, int32_t hashAlg) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace("Server "); } @@ -1408,15 +1491,15 @@ void psPrintTranscriptHashUpdate(ssl_t *ssl, } if (hashAlg == OID_SHA384_ALG) { - tlsTrace("SHA-384:"); + tlsTrace("SHA-384"); } else if (hashAlg == OID_SHA256_ALG) { - tlsTrace("SHA-256:"); + tlsTrace("SHA-256"); } else { - tlsTrace("Unknown digest:"); + tlsTrace("Unknown digest"); } tlsTrace(":\n"); psTraceBytes("Tr-Hash input", in, inLen); @@ -1737,6 +1820,7 @@ void psPrintPubKeyTypeAndSize(ssl_t *ssl, } } +# ifndef USE_ONLY_PSK_CIPHER_SUITE static void psPrintPubKeyTypeAndSizeRaw(ssl_t *ssl, uint8_t keyType, @@ -1766,13 +1850,13 @@ void psPrintPubKeyTypeAndSizeRaw(ssl_t *ssl, tlsTrace("DHE"); break; case PS_DSA: - tlsTrace("DSA\n"); + tlsTrace("DSA"); break; case PS_X25519: - tlsTrace("X25519\n"); + tlsTrace("X25519"); break; case PS_ED25519: - tlsTrace("Ed25519\n"); + tlsTrace("Ed25519"); break; default: tlsTraceInt("Unknown/unsupported key type: %hhu", keyType); @@ -1780,6 +1864,7 @@ void psPrintPubKeyTypeAndSizeRaw(ssl_t *ssl, tlsTraceInt(" (%hu-bit)\n", keyNBits); } +# endif /* USE_ONLY_PSK_CIPHER_SUITE */ /* Print out information about a completed handshake. */ void matrixSslPrintHSDetails(ssl_t *ssl) @@ -1793,7 +1878,7 @@ void matrixSslPrintHSDetails(ssl_t *ssl) psTracePrintCiphersuiteName(INDENT_CONN_ESTABLISHED, NULL, ssl->cipher->ident, PS_TRUE); - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(" MatrixSSL server\n"); } @@ -1804,11 +1889,15 @@ void matrixSslPrintHSDetails(ssl_t *ssl) if (RESUMED_HANDSHAKE(ssl)) { tlsTrace(" Resumed session\n"); + /* + In resumed handshakes, neither authentication nor key exchange + is performed, and don't keep the previous keys in memory. + So no sig alg or key ex information to print here. + */ + return; } - else - { - tlsTrace(" New session\n"); - } + + tlsTrace(" New session\n"); # ifdef USE_TLS_1_3 if (NGTD_VER(ssl, v_tls_1_3_any)) { @@ -1843,7 +1932,7 @@ void matrixSslPrintHSDetails(ssl_t *ssl) # ifndef USE_ONLY_PSK_CIPHER_SUITE if (ssl->sec.tls13CvSigAlg != 0) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(" Server sig alg: "); } @@ -1854,8 +1943,9 @@ void matrixSslPrintHSDetails(ssl_t *ssl) psTracePrintTls13SigAlg(INDENT_CONN_ESTABLISHED, NULL, ssl->sec.tls13CvSigAlg, + PS_FALSE, PS_TRUE); - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(" Server key: "); } @@ -1868,7 +1958,7 @@ void matrixSslPrintHSDetails(ssl_t *ssl) } if (ssl->sec.tls13PeerCvSigAlg != 0) { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(" Client sig alg: "); } @@ -1879,9 +1969,10 @@ void matrixSslPrintHSDetails(ssl_t *ssl) psTracePrintTls13SigAlg(INDENT_CONN_ESTABLISHED, NULL, ssl->sec.tls13PeerCvSigAlg, + PS_FALSE, PS_TRUE); # ifdef USE_CERT_PARSE - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(" Client key: "); } @@ -1895,7 +1986,7 @@ void matrixSslPrintHSDetails(ssl_t *ssl) } else { - if (IS_SERVER(ssl)) + if (MATRIX_IS_SERVER(ssl)) { tlsTrace(" No client authentication\n"); } @@ -1904,7 +1995,7 @@ void matrixSslPrintHSDetails(ssl_t *ssl) } } /* endif(TLS 1.3) */ # endif -# ifndef USE_ONLY_PSK_CIPHERSUITE +# ifndef USE_ONLY_PSK_CIPHER_SUITE if (!NGTD_VER(ssl, v_tls_1_3_any)) { if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) @@ -1915,56 +2006,65 @@ void matrixSslPrintHSDetails(ssl_t *ssl) { tlsTrace(" No client authentication\n"); } - if (IS_SERVER(ssl)) +# ifdef USE_IDENTITY_CERTIFICATES + if (!RESUMED_HANDSHAKE(ssl)) { - if (ssl->keys && ssl->chosenIdentity) + if (MATRIX_IS_SERVER(ssl)) { - tlsTrace(" Server key: "); - psTracePrintPubKeyTypeAndSize(ssl, - &ssl->chosenIdentity->privKey); + if (ssl->keys && ssl->chosenIdentity) + { + tlsTrace(" Server key: "); + psTracePrintPubKeyTypeAndSize(ssl, + &ssl->chosenIdentity->privKey); + } + if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) + { + tlsTrace(" Client key: "); + psPrintPubKeyTypeAndSizeRaw(ssl, + ssl->peerAuthKeyType, + ssl->peerAuthKeyNBits, + PS_FALSE); + } } - if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) + else /* We are client. */ { - tlsTrace(" Client key: "); + if ((ssl->flags & SSL_FLAGS_CLIENT_AUTH) + && ssl->chosenIdentity) + { + tlsTrace(" Client key: "); + psTracePrintPubKeyTypeAndSize(ssl, + &ssl->chosenIdentity->privKey); + } + tlsTrace(" Server key: "); psPrintPubKeyTypeAndSizeRaw(ssl, ssl->peerAuthKeyType, ssl->peerAuthKeyNBits, PS_FALSE); } } - else /* We are client. */ +# endif /* USE_IDENTITY_CERTIFICATES */ + if (!RESUMED_HANDSHAKE(ssl)) { - if ((ssl->flags & SSL_FLAGS_CLIENT_AUTH) && ssl->chosenIdentity) + tlsTrace(" Key exchange: "); + if (ssl->flags & SSL_FLAGS_PSK_CIPHER) { - tlsTrace(" Client key: "); - psTracePrintPubKeyTypeAndSize(ssl, - &ssl->chosenIdentity->privKey); - } - tlsTrace(" Server key: "); - psPrintPubKeyTypeAndSizeRaw(ssl, - ssl->peerAuthKeyType, - ssl->peerAuthKeyNBits, - PS_FALSE); - } - tlsTrace(" Key exchange: "); - if (ssl->flags & SSL_FLAGS_PSK_CIPHER) - { - tlsTrace("PSK\n"); - } - else - { - /* We are not using PSK and we only filled - ssl->peerKeyExKeyType if we used (EC)DH. */ - if (ssl->peerKeyExKeyType == 0) - { - tlsTrace("RSA key transport\n"); + tlsTrace("PSK\n"); } else { - psPrintPubKeyTypeAndSizeRaw(ssl, - ssl->peerKeyExKeyType, - ssl->peerKeyExKeyNBits, - PS_TRUE); + /* We are not using PSK and we only filled + ssl->peerKeyExKeyType if we used (EC)DH. */ + if (ssl->peerKeyExKeyType == 0) + { + tlsTrace("RSA key transport\n"); + } + else + { + psPrintPubKeyTypeAndSizeRaw(ssl, + ssl->peerKeyExKeyType, + ssl->peerKeyExKeyNBits, + PS_TRUE); + } } } } diff --git a/matrixssl/version.h b/matrixssl/version.h index ec6c52b..311d1f9 100644 --- a/matrixssl/version.h +++ b/matrixssl/version.h @@ -1,5 +1,5 @@ /* - Copyright 2018 INSIDE Secure Corporation + Copyright 2019 INSIDE Secure Corporation This file is auto-generated */ #ifndef _h_MATRIXSSL_VERSION @@ -8,10 +8,10 @@ extern "C" { #endif -#define MATRIXSSL_VERSION "4.0.1-OPEN" +#define MATRIXSSL_VERSION "4.1.0-OPEN" #define MATRIXSSL_VERSION_MAJOR 4 -#define MATRIXSSL_VERSION_MINOR 0 -#define MATRIXSSL_VERSION_PATCH 1 +#define MATRIXSSL_VERSION_MINOR 1 +#define MATRIXSSL_VERSION_PATCH 0 #define MATRIXSSL_VERSION_CODE "OPEN" #ifdef __cplusplus diff --git a/readme.txt b/readme.txt index 41f64a9..c310304 100644 --- a/readme.txt +++ b/readme.txt @@ -37,6 +37,11 @@ crypto/ test/ Functionality and performance tests. +* crypto-rot/ + Inside Secure Root-of-Trust based crypto provider. This can be + used instead of the standard software crypto implementation by + defining USE_ROT_CRYPTO in cryptoConfig.h. + * crypto-cl/ SafeZone Cryptographic Library Integration. This directory replaces (the most) contents of crypto library when compiling with default, diff --git a/doc/CHANGES_v4.0.html b/release_notes-4-1-0-open.html similarity index 79% rename from doc/CHANGES_v4.0.html rename to release_notes-4-1-0-open.html index 08ce9e3..783b17c 100644 --- a/doc/CHANGES_v4.0.html +++ b/release_notes-4-1-0-open.html @@ -9,6 +9,26 @@

MatrixSSL 4.x changelog

+

Changes between 4.0.2 and 4.1.0 [April 2019]

+
    +
  • TLS:

    +
      +
    • (RoT Edition only): Added support for Inside Secure VaultIP (Root-of-Trust) crypto provider.

    • +
    • Improved the separation of private and public TLS header files for better private-public separation. The public headers now of the form matrixsslApi*.h, while private headers are of the form matrixssllib_*.h.

    • +
    • Added client-side support for X25519 in TLS 1.2.

    • +
    • Added client-side support for RSASSA-PSS signatures in TLS 1.2.

    • +
    • Added support for RSASSA-PSS key/cert pairs.

    • +
    • Fix vulnerabilities reported by Robert Święcki (discovered using Hongfuzzer): a server-side heap buffer read overflow when parsing maliciously crafted ClientHello extensions and a segfault in TLS 1.2 GCM decryption of maliciously crafted records with small ciphertext.

    • +
    • Added the simpleClient.c and simpleServer.c example applications. These are intended as minimalistic examples of how to use the top-level TLS API.

    • +
    • Fixed bugs in matrixSslSessOptsServerTlsVersionRange and matrixSslSessOptsClientTlsVersionRange.

    • +
    • Fixed bug that caused non-insitu app data encryption to fail in tls13EncodeAppData when using the matrixSslEncodeToOutdata API instead of the more standard matrixSslGetWriteBuf + matrixSslEncodeWritebuf pattern.

    • +
    • Added new minimal example configurations: tls12-minimal, tls12-minimal-client-ecc, tls13-minimal, tls13-minimal-client-ecc

    • +
    • When performing TLS 1.2 renegotiation, re-send the original ClientHello cipher list.

    • +
    • Added the USE_LENIENT_TLS_RECORD_VERSION_MATCHING compatibility option.

    • +
  • +
+

Changes between 4.0.1 and 4.0.2 [February 2019]

+

This version fixes a critical vulnerability in RSA signature verification. A maliciously crafted certificate can be used to trigger a stack buffer overflow, allowing potential remote code execution attacks. The vulnerability only affects version 4.0.1 and the standard Matrix Crypto provider. Other providers, such as the FIPS crypto provider, are not affected by the bug. Thanks to Tavis Ormandy for reporting this.

Changes between 4.0.0 and 4.0.1 [November 2018]

This version improves the security of RSA PKCS #1.5 signature verification and adds better support for run-time security configuration.

    diff --git a/testkeys/EC/384_EC_CA_SHA384.h b/testkeys/EC/384_EC_CA_SHA384.h new file mode 100644 index 0000000..e5104c4 --- /dev/null +++ b/testkeys/EC/384_EC_CA_SHA384.h @@ -0,0 +1,75 @@ +/** + * @file 384_EC_CA.h + * + * Binary file for including certificate to MatrixSSL. + */ +static const unsigned char EC384CA[] = { + 0x30, 0x82, 0x03, 0x16, 0x30, 0x82, 0x02, 0x9c, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0x8f, 0xec, 0x98, 0x2c, 0x87, 0xce, 0xf2, 0x18, + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, + 0x30, 0x81, 0xbd, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, + 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x33, 0x30, 0x31, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x53, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x45, 0x43, 0x2d, + 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x30, 0x38, 0x31, 0x33, + 0x34, 0x34, 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x30, + 0x38, 0x31, 0x33, 0x34, 0x34, 0x34, 0x36, 0x5a, 0x30, 0x81, 0xbd, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x46, + 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, + 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x19, + 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, + 0x54, 0x65, 0x73, 0x74, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x2a, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x4d, 0x61, + 0x74, 0x72, 0x69, 0x78, 0x20, 0x45, 0x43, 0x2d, 0x33, 0x38, 0x34, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, + 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x30, 0x76, 0x30, 0x10, + 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, + 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0x9e, 0x04, 0x34, 0x99, + 0xef, 0x8a, 0x25, 0x1d, 0x84, 0xf2, 0xf2, 0x40, 0xc4, 0xd5, 0xd1, 0x53, + 0x7d, 0x54, 0xec, 0x20, 0x36, 0xdf, 0x1a, 0xe2, 0xe4, 0x70, 0xf8, 0xd3, + 0x39, 0xa0, 0x39, 0x18, 0x3d, 0xb1, 0xfa, 0x2d, 0xec, 0xa2, 0xc1, 0x46, + 0xdf, 0x6d, 0x94, 0x8f, 0xde, 0xdc, 0xd2, 0x3d, 0x19, 0x2f, 0x16, 0xec, + 0x52, 0x58, 0x3a, 0x80, 0xc1, 0xc3, 0xbf, 0x85, 0x27, 0x16, 0x42, 0x07, + 0xe0, 0x02, 0xf1, 0xd7, 0x95, 0xc9, 0x10, 0xec, 0xb0, 0xa0, 0x98, 0x8a, + 0x42, 0xb5, 0x51, 0xe8, 0x21, 0xfb, 0x29, 0xaf, 0xf9, 0x45, 0xa8, 0xb2, + 0x76, 0x10, 0x46, 0xef, 0xe4, 0xec, 0xdf, 0xc1, 0xa3, 0x66, 0x30, 0x64, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x44, 0xed, 0xfc, 0x8b, 0x17, + 0x42, 0x6e, 0x61, 0xf6, 0x35, 0x93, 0x3d, 0x3f, 0x81, 0x97, 0x6f, 0x67, + 0x68, 0x5a, 0x1b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x44, 0xed, 0xfc, 0x8b, 0x17, 0x42, 0x6e, 0x61, + 0xf6, 0x35, 0x93, 0x3d, 0x3f, 0x81, 0x97, 0x6f, 0x67, 0x68, 0x5a, 0x1b, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, + 0x03, 0x02, 0x00, 0x04, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x03, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x6f, + 0xac, 0xeb, 0x76, 0x0d, 0xce, 0xc7, 0x90, 0x29, 0xa0, 0x3c, 0xf3, 0xdc, + 0x61, 0x55, 0xe5, 0x83, 0xbf, 0x7a, 0xdf, 0x3c, 0xcd, 0x08, 0xb3, 0x46, + 0xa9, 0xd0, 0x9a, 0x57, 0x43, 0xb3, 0xcb, 0xcb, 0x91, 0xdd, 0x1d, 0x72, + 0x44, 0xc5, 0x10, 0x8a, 0x92, 0x3a, 0xc8, 0x99, 0xfb, 0x1a, 0x3d, 0x02, + 0x31, 0x00, 0x80, 0x03, 0x4d, 0x11, 0x54, 0x32, 0xa2, 0xc9, 0x13, 0xbe, + 0x58, 0x15, 0x7b, 0xfd, 0xf3, 0xb3, 0xd9, 0x15, 0xda, 0x40, 0x1c, 0xa2, + 0x04, 0x24, 0x3d, 0x2b, 0xa8, 0x1d, 0xf5, 0xf0, 0xee, 0xa8, 0x75, 0x59, + 0x6b, 0xc1, 0x7d, 0x1b, 0xc3, 0x55, 0xb4, 0x8f, 0x1f, 0xb8, 0x70, 0x10, + 0x61, 0xca +}; +#define EC384CA_SIZE 794 diff --git a/testkeys/EC/384_EC_CA_SHA384.pem b/testkeys/EC/384_EC_CA_SHA384.pem new file mode 100644 index 0000000..32ba9e3 --- /dev/null +++ b/testkeys/EC/384_EC_CA_SHA384.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCApygAwIBAgIJAI/smCyHzvIYMAoGCCqGSM49BAMDMIG9MQswCQYDVQQG +EwJGSTEQMA4GA1UECAwHRmlubGFuZDERMA8GA1UEBwwISGVsc2lua2kxIjAgBgNV +BAoMGUlOU0lERSBTZWN1cmUgQ29ycG9yYXRpb24xDTALBgNVBAsMBFRlc3QxMzAx +BgNVBAMMKlNhbXBsZSBNYXRyaXggRUMtMzg0IENlcnRpZmljYXRlIEF1dGhvcml0 +eTEhMB8GCSqGSIb3DQEJARYSdGVzdEBlbWFpbC5hZGRyZXNzMB4XDTE5MDIwODEz +NDQ0NloXDTI5MDIwODEzNDQ0Nlowgb0xCzAJBgNVBAYTAkZJMRAwDgYDVQQIDAdG +aW5sYW5kMREwDwYDVQQHDAhIZWxzaW5raTEiMCAGA1UECgwZSU5TSURFIFNlY3Vy +ZSBDb3Jwb3JhdGlvbjENMAsGA1UECwwEVGVzdDEzMDEGA1UEAwwqU2FtcGxlIE1h +dHJpeCBFQy0zODQgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkB +FhJ0ZXN0QGVtYWlsLmFkZHJlc3MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASeBDSZ +74olHYTy8kDE1dFTfVTsIDbfGuLkcPjTOaA5GD2x+i3sosFG322Uj97c0j0ZLxbs +Ulg6gMHDv4UnFkIH4ALx15XJEOywoJiKQrVR6CH7Ka/5RaiydhBG7+Ts38GjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFETt/IsXQm5h9jWTPT+Bl29n +aFobMB8GA1UdIwQYMBaAFETt/IsXQm5h9jWTPT+Bl29naFobMA4GA1UdDwEB/wQE +AwIABDAKBggqhkjOPQQDAwNoADBlAjBvrOt2Dc7HkCmgPPPcYVXlg7963zzNCLNG +qdCaV0Ozy8uR3R1yRMUQipI6yJn7Gj0CMQCAA00RVDKiyRO+WBV7/fOz2RXaQByi +BCQ9K6gd9fDuqHVZa8F9G8NVtI8fuHAQYco= +-----END CERTIFICATE----- diff --git a/testkeys/EC/384_EC_PUB.pem b/testkeys/EC/384_EC_PUB.pem new file mode 100644 index 0000000..07bebca --- /dev/null +++ b/testkeys/EC/384_EC_PUB.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAESwFzwJK1UKp/ACHebnAbl3Bx/JSTe18J +eFdrQ1VDGSEQknlXy0QpUN/JcgTawEM35c0IbJjt+5Vx+KWItxInUbgQexT9KSPo +RRA/gYT49qfIKmuoL4ueKW78FfEj5SNL +-----END PUBLIC KEY----- diff --git a/testkeys/EC/384_EC_SHA384.h b/testkeys/EC/384_EC_SHA384.h new file mode 100644 index 0000000..f4cfe71 --- /dev/null +++ b/testkeys/EC/384_EC_SHA384.h @@ -0,0 +1,77 @@ +/** + * @file 384_EC.h + * + * Binary file for including certificate to MatrixSSL. + */ +static const unsigned char EC384[] = { + 0x30, 0x82, 0x03, 0x35, 0x30, 0x82, 0x02, 0xbb, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x03, 0x30, 0x81, 0xbd, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, + 0x6e, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, + 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, + 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, + 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, + 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x53, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0x20, 0x45, 0x43, 0x2d, 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, + 0x73, 0x74, 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, + 0x30, 0x38, 0x31, 0x33, 0x34, 0x34, 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x32, + 0x39, 0x30, 0x32, 0x30, 0x38, 0x31, 0x33, 0x34, 0x34, 0x34, 0x36, 0x5a, + 0x30, 0x81, 0xb3, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, + 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x29, 0x30, 0x27, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x53, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x45, 0x43, 0x2d, + 0x33, 0x38, 0x34, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, + 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, + 0x00, 0x04, 0x4b, 0x01, 0x73, 0xc0, 0x92, 0xb5, 0x50, 0xaa, 0x7f, 0x00, + 0x21, 0xde, 0x6e, 0x70, 0x1b, 0x97, 0x70, 0x71, 0xfc, 0x94, 0x93, 0x7b, + 0x5f, 0x09, 0x78, 0x57, 0x6b, 0x43, 0x55, 0x43, 0x19, 0x21, 0x10, 0x92, + 0x79, 0x57, 0xcb, 0x44, 0x29, 0x50, 0xdf, 0xc9, 0x72, 0x04, 0xda, 0xc0, + 0x43, 0x37, 0xe5, 0xcd, 0x08, 0x6c, 0x98, 0xed, 0xfb, 0x95, 0x71, 0xf8, + 0xa5, 0x88, 0xb7, 0x12, 0x27, 0x51, 0xb8, 0x10, 0x7b, 0x14, 0xfd, 0x29, + 0x23, 0xe8, 0x45, 0x10, 0x3f, 0x81, 0x84, 0xf8, 0xf6, 0xa7, 0xc8, 0x2a, + 0x6b, 0xa8, 0x2f, 0x8b, 0x9e, 0x29, 0x6e, 0xfc, 0x15, 0xf1, 0x23, 0xe5, + 0x23, 0x4b, 0xa3, 0x81, 0x96, 0x30, 0x81, 0x93, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xc8, 0x30, 0x1a, 0x06, 0x03, + 0x55, 0x1d, 0x11, 0x04, 0x13, 0x30, 0x11, 0x82, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa3, 0x37, 0x0f, 0xe5, 0x90, 0x82, + 0x27, 0xa3, 0x9e, 0xa4, 0x99, 0x09, 0x8b, 0xe8, 0x6e, 0x5a, 0x11, 0x94, + 0xad, 0xb1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0x44, 0xed, 0xfc, 0x8b, 0x17, 0x42, 0x6e, 0x61, 0xf6, + 0x35, 0x93, 0x3d, 0x3f, 0x81, 0x97, 0x6f, 0x67, 0x68, 0x5a, 0x1b, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, 0x03, + 0x68, 0x00, 0x30, 0x65, 0x02, 0x30, 0x1b, 0xe0, 0x44, 0x54, 0x29, 0xc9, + 0x22, 0xaf, 0xa7, 0xfd, 0xd3, 0x1d, 0xdd, 0x81, 0xa5, 0x47, 0x25, 0x0a, + 0xf6, 0xb9, 0x0b, 0x3b, 0xc2, 0x7a, 0x60, 0xc9, 0x70, 0xde, 0xe5, 0x37, + 0xef, 0x7c, 0x2d, 0xaa, 0x7d, 0xd0, 0xa9, 0xc2, 0x2f, 0x91, 0x10, 0xd9, + 0xd1, 0x1e, 0x0e, 0x60, 0x66, 0x33, 0x02, 0x31, 0x00, 0xef, 0x97, 0xf4, + 0x5b, 0x66, 0x89, 0x40, 0x8f, 0xeb, 0x1d, 0xd5, 0xb4, 0xeb, 0x7e, 0x35, + 0x4e, 0x22, 0x82, 0xbf, 0x80, 0x83, 0x86, 0x3a, 0x91, 0xcc, 0x02, 0xfc, + 0xf1, 0x64, 0x96, 0xdd, 0x5e, 0x95, 0xa3, 0x69, 0x21, 0x0c, 0x5f, 0xbf, + 0x49, 0x8e, 0x96, 0x8a, 0x5c, 0x6c, 0x05, 0xe6, 0x99 +}; +#define EC384_SIZE 825 diff --git a/testkeys/EC/384_EC_SHA384.pem b/testkeys/EC/384_EC_SHA384.pem new file mode 100644 index 0000000..79adbd2 --- /dev/null +++ b/testkeys/EC/384_EC_SHA384.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCArugAwIBAgIBATAKBggqhkjOPQQDAzCBvTELMAkGA1UEBhMCRkkxEDAO +BgNVBAgMB0ZpbmxhbmQxETAPBgNVBAcMCEhlbHNpbmtpMSIwIAYDVQQKDBlJTlNJ +REUgU2VjdXJlIENvcnBvcmF0aW9uMQ0wCwYDVQQLDARUZXN0MTMwMQYDVQQDDCpT +YW1wbGUgTWF0cml4IEVDLTM4NCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxITAfBgkq +hkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczAeFw0xOTAyMDgxMzQ0NDZaFw0y +OTAyMDgxMzQ0NDZaMIGzMQswCQYDVQQGEwJGSTEQMA4GA1UECAwHRmlubGFuZDER +MA8GA1UEBwwISGVsc2lua2kxIjAgBgNVBAoMGUlOU0lERSBTZWN1cmUgQ29ycG9y +YXRpb24xDTALBgNVBAsMBFRlc3QxKTAnBgNVBAMMIFNhbXBsZSBNYXRyaXggRUMt +Mzg0IENlcnRpZmljYXRlMSEwHwYJKoZIhvcNAQkBFhJ0ZXN0QGVtYWlsLmFkZHJl +c3MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLAXPAkrVQqn8AId5ucBuXcHH8lJN7 +Xwl4V2tDVUMZIRCSeVfLRClQ38lyBNrAQzflzQhsmO37lXH4pYi3EidRuBB7FP0p +I+hFED+BhPj2p8gqa6gvi54pbvwV8SPlI0ujgZYwgZMwCQYDVR0TBAIwADALBgNV +HQ8EBAMCA8gwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUozcP5ZCCJ6OepJkJi+huWhGU +rbEwHwYDVR0jBBgwFoAURO38ixdCbmH2NZM9P4GXb2doWhswCgYIKoZIzj0EAwMD +aAAwZQIwG+BEVCnJIq+n/dMd3YGlRyUK9rkLO8J6YMlw3uU373wtqn3QqcIvkRDZ +0R4OYGYzAjEA75f0W2aJQI/rHdW06341TiKCv4CDhjqRzAL88WSW3V6Vo2khDF+/ +SY6WilxsBeaZ +-----END CERTIFICATE----- diff --git a/testkeys/EC/521_EC_CA_SHA512.h b/testkeys/EC/521_EC_CA_SHA512.h new file mode 100644 index 0000000..5f1b9b8 --- /dev/null +++ b/testkeys/EC/521_EC_CA_SHA512.h @@ -0,0 +1,81 @@ +/** + * @file 521_EC_CA.h + * + * Binary file for including certificate to MatrixSSL. + */ +static const unsigned char EC521CA[] = { + 0x30, 0x82, 0x03, 0x60, 0x30, 0x82, 0x02, 0xc2, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0xa4, 0xeb, 0xbb, 0x0b, 0xb2, 0x38, 0xd4, 0xf3, + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, + 0x30, 0x81, 0xbd, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, + 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x33, 0x30, 0x31, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x53, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x45, 0x43, 0x2d, + 0x35, 0x32, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x30, 0x38, 0x31, 0x35, + 0x31, 0x39, 0x30, 0x33, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x30, + 0x38, 0x31, 0x35, 0x31, 0x39, 0x30, 0x33, 0x5a, 0x30, 0x81, 0xbd, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x46, + 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, + 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x19, + 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, + 0x54, 0x65, 0x73, 0x74, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x2a, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x4d, 0x61, + 0x74, 0x72, 0x69, 0x78, 0x20, 0x45, 0x43, 0x2d, 0x35, 0x32, 0x31, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, + 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x30, 0x81, 0x9b, 0x30, + 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, + 0x2b, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, 0x00, 0x04, 0x01, 0x2b, + 0x43, 0xd8, 0x8d, 0x9f, 0xd5, 0x2f, 0x9d, 0x55, 0x0b, 0xfe, 0x72, 0x0b, + 0x32, 0xd7, 0x8e, 0x42, 0xc4, 0x02, 0x97, 0xb3, 0xcd, 0x77, 0x15, 0xa1, + 0xea, 0xf6, 0x64, 0x35, 0x72, 0x72, 0x67, 0xb3, 0x5f, 0x77, 0x26, 0x6d, + 0x6f, 0x77, 0x2b, 0x4b, 0xa1, 0x9a, 0xdb, 0x8c, 0x76, 0xc4, 0xdc, 0x9d, + 0x60, 0x2d, 0x3b, 0x5e, 0x07, 0xf1, 0xa5, 0x75, 0x11, 0x22, 0x7a, 0xf5, + 0xef, 0x99, 0x77, 0x44, 0x00, 0xc4, 0x2d, 0xa7, 0x13, 0xc0, 0xc7, 0x8b, + 0xd5, 0x96, 0x92, 0x6d, 0xae, 0x84, 0x95, 0x25, 0x1f, 0xb0, 0x68, 0x7b, + 0x89, 0x75, 0xbf, 0x46, 0xb6, 0x9e, 0xa2, 0xac, 0x70, 0xf6, 0xec, 0x17, + 0x6e, 0x98, 0x2e, 0x0b, 0xac, 0x13, 0x78, 0x5f, 0x54, 0x8c, 0x00, 0xbd, + 0x3a, 0x8c, 0x5c, 0xd7, 0xa4, 0x86, 0xb5, 0x9c, 0x04, 0x67, 0x75, 0xe0, + 0xdc, 0x4d, 0x8a, 0x42, 0x46, 0xec, 0xe4, 0x5d, 0xf1, 0xaa, 0xa3, 0x66, + 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, + 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x19, 0xb0, 0xbe, + 0xa4, 0x9d, 0x8b, 0x3c, 0x44, 0xe5, 0x86, 0xb5, 0x17, 0xa1, 0xd6, 0x0d, + 0xba, 0x42, 0x1d, 0xb8, 0xa9, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x19, 0xb0, 0xbe, 0xa4, 0x9d, 0x8b, + 0x3c, 0x44, 0xe5, 0x86, 0xb5, 0x17, 0xa1, 0xd6, 0x0d, 0xba, 0x42, 0x1d, + 0xb8, 0xa9, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x00, 0x04, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, 0x03, 0x81, 0x8b, 0x00, 0x30, 0x81, + 0x87, 0x02, 0x41, 0x76, 0x00, 0x75, 0x70, 0xf2, 0x49, 0x1b, 0x5d, 0xea, + 0x82, 0xa5, 0xf1, 0x4b, 0x13, 0xc4, 0xe8, 0xbd, 0xf4, 0x39, 0xa2, 0x31, + 0x7f, 0x98, 0x58, 0x9a, 0x40, 0x48, 0xc0, 0x22, 0xa4, 0xab, 0x22, 0xd4, + 0x31, 0xe5, 0x8e, 0x61, 0xd4, 0xef, 0xcc, 0x0b, 0xc8, 0x78, 0x1b, 0x08, + 0x3f, 0x98, 0xac, 0xf1, 0xa9, 0x31, 0x94, 0xa5, 0x58, 0x60, 0x3a, 0xed, + 0xe7, 0x42, 0xd1, 0x01, 0x97, 0xd6, 0x4f, 0x09, 0x02, 0x42, 0x01, 0xfd, + 0x1e, 0x7c, 0x4a, 0x5a, 0xc1, 0xfd, 0x4c, 0x1d, 0x53, 0xa6, 0x9a, 0x2c, + 0xf2, 0x55, 0x2b, 0x09, 0xac, 0xc5, 0x34, 0x38, 0xc3, 0xcd, 0x3b, 0x9e, + 0x55, 0x0e, 0x5e, 0x9c, 0xbd, 0x95, 0x3a, 0x01, 0xdb, 0x0c, 0x85, 0x93, + 0x86, 0xab, 0xb7, 0x5a, 0x2e, 0xae, 0x98, 0x12, 0x23, 0x70, 0x10, 0x93, + 0xd4, 0x64, 0x42, 0x76, 0xe8, 0x74, 0x47, 0x4e, 0x95, 0x70, 0x54, 0x3b, + 0x6d, 0xa5, 0xc3, 0x36 +}; +#define EC521CA_SIZE 868 diff --git a/testkeys/EC/521_EC_CA_SHA512.pem b/testkeys/EC/521_EC_CA_SHA512.pem new file mode 100644 index 0000000..4a4db53 --- /dev/null +++ b/testkeys/EC/521_EC_CA_SHA512.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDYDCCAsKgAwIBAgIJAKTruwuyONTzMAoGCCqGSM49BAMEMIG9MQswCQYDVQQG +EwJGSTEQMA4GA1UECAwHRmlubGFuZDERMA8GA1UEBwwISGVsc2lua2kxIjAgBgNV +BAoMGUlOU0lERSBTZWN1cmUgQ29ycG9yYXRpb24xDTALBgNVBAsMBFRlc3QxMzAx +BgNVBAMMKlNhbXBsZSBNYXRyaXggRUMtNTIxIENlcnRpZmljYXRlIEF1dGhvcml0 +eTEhMB8GCSqGSIb3DQEJARYSdGVzdEBlbWFpbC5hZGRyZXNzMB4XDTE5MDIwODE1 +MTkwM1oXDTI5MDIwODE1MTkwM1owgb0xCzAJBgNVBAYTAkZJMRAwDgYDVQQIDAdG +aW5sYW5kMREwDwYDVQQHDAhIZWxzaW5raTEiMCAGA1UECgwZSU5TSURFIFNlY3Vy +ZSBDb3Jwb3JhdGlvbjENMAsGA1UECwwEVGVzdDEzMDEGA1UEAwwqU2FtcGxlIE1h +dHJpeCBFQy01MjEgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkB +FhJ0ZXN0QGVtYWlsLmFkZHJlc3MwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAEr +Q9iNn9UvnVUL/nILMteOQsQCl7PNdxWh6vZkNXJyZ7NfdyZtb3crS6Ga24x2xNyd +YC07XgfxpXURInr175l3RADELacTwMeL1ZaSba6ElSUfsGh7iXW/Rraeoqxw9uwX +bpguC6wTeF9UjAC9Ooxc16SGtZwEZ3Xg3E2KQkbs5F3xqqNmMGQwEgYDVR0TAQH/ +BAgwBgEB/wIBADAdBgNVHQ4EFgQUGbC+pJ2LPETlhrUXodYNukIduKkwHwYDVR0j +BBgwFoAUGbC+pJ2LPETlhrUXodYNukIduKkwDgYDVR0PAQH/BAQDAgAEMAoGCCqG +SM49BAMEA4GLADCBhwJBdgB1cPJJG13qgqXxSxPE6L30OaIxf5hYmkBIwCKkqyLU +MeWOYdTvzAvIeBsIP5is8akxlKVYYDrt50LRAZfWTwkCQgH9HnxKWsH9TB1Tppos +8lUrCazFNDjDzTueVQ5enL2VOgHbDIWThqu3Wi6umBIjcBCT1GRCduh0R06VcFQ7 +baXDNg== +-----END CERTIFICATE----- diff --git a/testkeys/EC/521_EC_SHA512.h b/testkeys/EC/521_EC_SHA512.h new file mode 100644 index 0000000..69167c1 --- /dev/null +++ b/testkeys/EC/521_EC_SHA512.h @@ -0,0 +1,83 @@ +/** + * @file 521_EC.h + * + * Binary file for including certificate to MatrixSSL. + */ +static const unsigned char EC521[] = { + 0x30, 0x82, 0x03, 0x7f, 0x30, 0x82, 0x02, 0xe1, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x04, 0x30, 0x81, 0xbd, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, + 0x6e, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, + 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, + 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, + 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, + 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, + 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a, 0x53, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0x20, 0x45, 0x43, 0x2d, 0x35, 0x32, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, + 0x73, 0x74, 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, + 0x30, 0x38, 0x31, 0x35, 0x31, 0x39, 0x30, 0x33, 0x5a, 0x17, 0x0d, 0x32, + 0x39, 0x30, 0x32, 0x30, 0x38, 0x31, 0x35, 0x31, 0x39, 0x30, 0x33, 0x5a, + 0x30, 0x81, 0xb3, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, + 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x29, 0x30, 0x27, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x53, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x45, 0x43, 0x2d, + 0x35, 0x32, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, + 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x30, 0x81, 0x9b, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, 0x03, + 0x81, 0x86, 0x00, 0x04, 0x00, 0x0a, 0x5a, 0x3b, 0xb8, 0xc6, 0x16, 0x85, + 0x2e, 0x87, 0x67, 0xa6, 0x7b, 0x5c, 0x6e, 0x29, 0x8a, 0x5e, 0xe2, 0x11, + 0x03, 0x83, 0x28, 0x20, 0x58, 0x3e, 0xd3, 0x5a, 0xb5, 0x68, 0xd9, 0xb7, + 0xef, 0xec, 0x16, 0x95, 0xc1, 0xe8, 0x7d, 0xb8, 0x07, 0xf4, 0x16, 0x50, + 0x3d, 0x30, 0x61, 0x78, 0x95, 0x75, 0xeb, 0x68, 0x0a, 0x0b, 0xff, 0x5e, + 0x08, 0x5d, 0x75, 0x66, 0x01, 0xaf, 0x29, 0x1f, 0xd5, 0x5d, 0x00, 0xc5, + 0xf3, 0x4d, 0x5a, 0x63, 0xef, 0x07, 0x49, 0xae, 0x89, 0x75, 0xb2, 0x9a, + 0xa0, 0x6b, 0x45, 0x6f, 0x4f, 0xd5, 0xb3, 0x47, 0xa3, 0xcc, 0x7c, 0xac, + 0x11, 0x24, 0x89, 0x9a, 0x5d, 0x63, 0xba, 0x85, 0xc2, 0xcf, 0xc3, 0x7b, + 0x43, 0xd2, 0xce, 0xfd, 0xdc, 0xea, 0x96, 0x76, 0xad, 0xa4, 0x61, 0x8a, + 0xa3, 0xfb, 0xa6, 0x26, 0x68, 0x50, 0x2e, 0x80, 0x82, 0xad, 0x71, 0xc5, + 0xf8, 0xcb, 0x20, 0xee, 0xa3, 0x81, 0x96, 0x30, 0x81, 0x93, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xc8, 0x30, 0x1a, + 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x13, 0x30, 0x11, 0x82, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x87, 0x04, 0x7f, 0x00, + 0x00, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, + 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x26, 0x3b, 0x12, 0xbd, + 0x2f, 0xa1, 0x9f, 0x3f, 0xd8, 0x35, 0xe3, 0xd1, 0x83, 0x23, 0x21, 0xeb, + 0x35, 0xda, 0xd7, 0x86, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0x19, 0xb0, 0xbe, 0xa4, 0x9d, 0x8b, 0x3c, + 0x44, 0xe5, 0x86, 0xb5, 0x17, 0xa1, 0xd6, 0x0d, 0xba, 0x42, 0x1d, 0xb8, + 0xa9, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, + 0x04, 0x03, 0x81, 0x8b, 0x00, 0x30, 0x81, 0x87, 0x02, 0x42, 0x01, 0x18, + 0x4a, 0xc8, 0x69, 0xbf, 0x33, 0x43, 0xd5, 0xcc, 0xec, 0x95, 0xc9, 0x7a, + 0xb5, 0xe3, 0xa6, 0x1b, 0xb8, 0xc9, 0x63, 0x9f, 0x13, 0xca, 0x1e, 0x87, + 0xdc, 0x92, 0x6e, 0x85, 0xa0, 0x89, 0x41, 0xc5, 0x69, 0x5f, 0x1f, 0xd6, + 0xd3, 0x6c, 0xe9, 0x59, 0xe2, 0x9a, 0x1d, 0xd1, 0x8d, 0x58, 0x94, 0xa4, + 0xc6, 0x48, 0x28, 0xf7, 0x0f, 0xcc, 0x1d, 0x12, 0x97, 0x2f, 0xa4, 0x84, + 0x10, 0x86, 0x84, 0x88, 0x02, 0x41, 0x0c, 0x97, 0x52, 0x36, 0x57, 0x51, + 0x3e, 0x75, 0xac, 0x56, 0x38, 0x7a, 0xa0, 0xf8, 0xf5, 0xb0, 0x06, 0x41, + 0xf4, 0x67, 0xbe, 0x96, 0xcb, 0x3b, 0x4a, 0xf6, 0xed, 0xf9, 0xed, 0xf6, + 0x00, 0xa9, 0x44, 0x53, 0xde, 0x39, 0x51, 0x2b, 0x65, 0x7c, 0xc5, 0x9d, + 0x91, 0x99, 0xe5, 0xf7, 0xc4, 0x64, 0xeb, 0xbb, 0x14, 0xaa, 0x77, 0xff, + 0x4d, 0x69, 0xe3, 0xce, 0xf8, 0x7b, 0xf0, 0xa4, 0xe4, 0x32, 0x2e +}; +#define EC521_SIZE 899 diff --git a/testkeys/EC/521_EC_SHA512.pem b/testkeys/EC/521_EC_SHA512.pem new file mode 100644 index 0000000..d5a4fbb --- /dev/null +++ b/testkeys/EC/521_EC_SHA512.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfzCCAuGgAwIBAgIBATAKBggqhkjOPQQDBDCBvTELMAkGA1UEBhMCRkkxEDAO +BgNVBAgMB0ZpbmxhbmQxETAPBgNVBAcMCEhlbHNpbmtpMSIwIAYDVQQKDBlJTlNJ +REUgU2VjdXJlIENvcnBvcmF0aW9uMQ0wCwYDVQQLDARUZXN0MTMwMQYDVQQDDCpT +YW1wbGUgTWF0cml4IEVDLTUyMSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxITAfBgkq +hkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczAeFw0xOTAyMDgxNTE5MDNaFw0y +OTAyMDgxNTE5MDNaMIGzMQswCQYDVQQGEwJGSTEQMA4GA1UECAwHRmlubGFuZDER +MA8GA1UEBwwISGVsc2lua2kxIjAgBgNVBAoMGUlOU0lERSBTZWN1cmUgQ29ycG9y +YXRpb24xDTALBgNVBAsMBFRlc3QxKTAnBgNVBAMMIFNhbXBsZSBNYXRyaXggRUMt +NTIxIENlcnRpZmljYXRlMSEwHwYJKoZIhvcNAQkBFhJ0ZXN0QGVtYWlsLmFkZHJl +c3MwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAAKWju4xhaFLodnpntcbimKXuIR +A4MoIFg+01q1aNm37+wWlcHofbgH9BZQPTBheJV162gKC/9eCF11ZgGvKR/VXQDF +801aY+8HSa6JdbKaoGtFb0/Vs0ejzHysESSJml1juoXCz8N7Q9LO/dzqlnatpGGK +o/umJmhQLoCCrXHF+Msg7qOBljCBkzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDyDAa +BgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwHQYDVR0lBBYwFAYIKwYBBQUHAwEG +CCsGAQUFBwMCMB0GA1UdDgQWBBQmOxK9L6GfP9g149GDIyHrNdrXhjAfBgNVHSME +GDAWgBQZsL6knYs8ROWGtReh1g26Qh24qTAKBggqhkjOPQQDBAOBiwAwgYcCQgEY +SshpvzND1czslcl6teOmG7jJY58Tyh6H3JJuhaCJQcVpXx/W02zpWeKaHdGNWJSk +xkgo9w/MHRKXL6SEEIaEiAJBDJdSNldRPnWsVjh6oPj1sAZB9Ge+lss7Svbt+e32 +AKlEU945UStlfMWdkZnl98Rk67sUqnf/TWnjzvh78KTkMi4= +-----END CERTIFICATE----- diff --git a/testkeys/EC/ALL_EC_CAS.pem b/testkeys/EC/ALL_EC_CAS.pem index 00e4e96..786dce1 100644 --- a/testkeys/EC/ALL_EC_CAS.pem +++ b/testkeys/EC/ALL_EC_CAS.pem @@ -90,3 +90,43 @@ PYW+6PSPf88LJIX56VtBhXc4JaHd/rdBBAVvRBs21wVwAkIBpKemM19o/W7/+76s NtpybpM/wbq/jQ6o9/wMGDFrWTXhaP84EsLz+aFLkBzestH+d0RBOpmouuLP+LCS 8+mIayQ= -----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDFjCCApygAwIBAgIJAI/smCyHzvIYMAoGCCqGSM49BAMDMIG9MQswCQYDVQQG +EwJGSTEQMA4GA1UECAwHRmlubGFuZDERMA8GA1UEBwwISGVsc2lua2kxIjAgBgNV +BAoMGUlOU0lERSBTZWN1cmUgQ29ycG9yYXRpb24xDTALBgNVBAsMBFRlc3QxMzAx +BgNVBAMMKlNhbXBsZSBNYXRyaXggRUMtMzg0IENlcnRpZmljYXRlIEF1dGhvcml0 +eTEhMB8GCSqGSIb3DQEJARYSdGVzdEBlbWFpbC5hZGRyZXNzMB4XDTE5MDIwODEz +NDQ0NloXDTI5MDIwODEzNDQ0Nlowgb0xCzAJBgNVBAYTAkZJMRAwDgYDVQQIDAdG +aW5sYW5kMREwDwYDVQQHDAhIZWxzaW5raTEiMCAGA1UECgwZSU5TSURFIFNlY3Vy +ZSBDb3Jwb3JhdGlvbjENMAsGA1UECwwEVGVzdDEzMDEGA1UEAwwqU2FtcGxlIE1h +dHJpeCBFQy0zODQgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkB +FhJ0ZXN0QGVtYWlsLmFkZHJlc3MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASeBDSZ +74olHYTy8kDE1dFTfVTsIDbfGuLkcPjTOaA5GD2x+i3sosFG322Uj97c0j0ZLxbs +Ulg6gMHDv4UnFkIH4ALx15XJEOywoJiKQrVR6CH7Ka/5RaiydhBG7+Ts38GjZjBk +MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFETt/IsXQm5h9jWTPT+Bl29n +aFobMB8GA1UdIwQYMBaAFETt/IsXQm5h9jWTPT+Bl29naFobMA4GA1UdDwEB/wQE +AwIABDAKBggqhkjOPQQDAwNoADBlAjBvrOt2Dc7HkCmgPPPcYVXlg7963zzNCLNG +qdCaV0Ozy8uR3R1yRMUQipI6yJn7Gj0CMQCAA00RVDKiyRO+WBV7/fOz2RXaQByi +BCQ9K6gd9fDuqHVZa8F9G8NVtI8fuHAQYco= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDYDCCAsKgAwIBAgIJAKTruwuyONTzMAoGCCqGSM49BAMEMIG9MQswCQYDVQQG +EwJGSTEQMA4GA1UECAwHRmlubGFuZDERMA8GA1UEBwwISGVsc2lua2kxIjAgBgNV +BAoMGUlOU0lERSBTZWN1cmUgQ29ycG9yYXRpb24xDTALBgNVBAsMBFRlc3QxMzAx +BgNVBAMMKlNhbXBsZSBNYXRyaXggRUMtNTIxIENlcnRpZmljYXRlIEF1dGhvcml0 +eTEhMB8GCSqGSIb3DQEJARYSdGVzdEBlbWFpbC5hZGRyZXNzMB4XDTE5MDIwODE1 +MTkwM1oXDTI5MDIwODE1MTkwM1owgb0xCzAJBgNVBAYTAkZJMRAwDgYDVQQIDAdG +aW5sYW5kMREwDwYDVQQHDAhIZWxzaW5raTEiMCAGA1UECgwZSU5TSURFIFNlY3Vy +ZSBDb3Jwb3JhdGlvbjENMAsGA1UECwwEVGVzdDEzMDEGA1UEAwwqU2FtcGxlIE1h +dHJpeCBFQy01MjEgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkB +FhJ0ZXN0QGVtYWlsLmFkZHJlc3MwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAEr +Q9iNn9UvnVUL/nILMteOQsQCl7PNdxWh6vZkNXJyZ7NfdyZtb3crS6Ga24x2xNyd +YC07XgfxpXURInr175l3RADELacTwMeL1ZaSba6ElSUfsGh7iXW/Rraeoqxw9uwX +bpguC6wTeF9UjAC9Ooxc16SGtZwEZ3Xg3E2KQkbs5F3xqqNmMGQwEgYDVR0TAQH/ +BAgwBgEB/wIBADAdBgNVHQ4EFgQUGbC+pJ2LPETlhrUXodYNukIduKkwHwYDVR0j +BBgwFoAUGbC+pJ2LPETlhrUXodYNukIduKkwDgYDVR0PAQH/BAQDAgAEMAoGCCqG +SM49BAMEA4GLADCBhwJBdgB1cPJJG13qgqXxSxPE6L30OaIxf5hYmkBIwCKkqyLU +MeWOYdTvzAvIeBsIP5is8akxlKVYYDrt50LRAZfWTwkCQgH9HnxKWsH9TB1Tppos +8lUrCazFNDjDzTueVQ5enL2VOgHbDIWThqu3Wi6umBIjcBCT1GRCduh0R06VcFQ7 +baXDNg== +-----END CERTIFICATE----- diff --git a/testkeys/EC/alt1/521_EC.pem b/testkeys/EC/alt1/521_EC.pem new file mode 100644 index 0000000..85a7085 --- /dev/null +++ b/testkeys/EC/alt1/521_EC.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAuGgAwIBAgIBATAKBggqhkjOPQQDBDCBvTELMAkGA1UEBhMCRkkxEDAO +BgNVBAgMB0ZpbmxhbmQxETAPBgNVBAcMCEhlbHNpbmtpMSIwIAYDVQQKDBlJTlNJ +REUgU2VjdXJlIENvcnBvcmF0aW9uMQ0wCwYDVQQLDARUZXN0MTMwMQYDVQQDDCpT +YW1wbGUgTWF0cml4IEVDLTUyMSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxITAfBgkq +hkiG9w0BCQEWEnRlc3RAZW1haWwuYWRkcmVzczAeFw0xOTAxMjkxMjAxMDFaFw0y +OTAxMjkxMjAxMDFaMIGzMQswCQYDVQQGEwJGSTEQMA4GA1UECAwHRmlubGFuZDER +MA8GA1UEBwwISGVsc2lua2kxIjAgBgNVBAoMGUlOU0lERSBTZWN1cmUgQ29ycG9y +YXRpb24xDTALBgNVBAsMBFRlc3QxKTAnBgNVBAMMIFNhbXBsZSBNYXRyaXggRUMt +NTIxIENlcnRpZmljYXRlMSEwHwYJKoZIhvcNAQkBFhJ0ZXN0QGVtYWlsLmFkZHJl +c3MwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAAga4T74ZMwM3UNIG+CeJmXtH9F +DLVdbN3VRjPJFTeUyu4UZ9320DEd3veUq4+ym3qO0xS19jKIbXLzlYJcl5dP8wEG +e84usY3LAyo+gLxK/pBSk/7hG9IxyyArydE7MoZueqeDakR2dD/mS8XIFRLqGIyz +ODN2n6WCq2DpVe1twVk7daOBljCBkzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDyDAa +BgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwHQYDVR0lBBYwFAYIKwYBBQUHAwEG +CCsGAQUFBwMCMB0GA1UdDgQWBBTWU5tm5cqwVtz8B8g59esY/oB0RzAfBgNVHSME +GDAWgBTBgRgeemHxjunHk4n+naDT9rp/ajAKBggqhkjOPQQDBAOBjAAwgYgCQgGM +rtapoGEJDjB5Rfchix9eZVmgjfdAQABwxsgIRUb5gNGu7djZC1IIHlBCf98mjGhQ +yzBu8F9BlBul3i3QQkjbnAJCAPuf1iCr0fkScj+fbHbxWodNY6Sd4zAmud0cyqI+ +WQzh0g+dQujcbuRQK+9X71Bx+UDzl79+fOmcHsyvRqhsJqvy +-----END CERTIFICATE----- diff --git a/testkeys/EC/alt1/521_EC_CA.pem b/testkeys/EC/alt1/521_EC_CA.pem new file mode 100644 index 0000000..7dc672c --- /dev/null +++ b/testkeys/EC/alt1/521_EC_CA.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXzCCAsKgAwIBAgIJANSjSItgW4DoMAoGCCqGSM49BAMEMIG9MQswCQYDVQQG +EwJGSTEQMA4GA1UECAwHRmlubGFuZDERMA8GA1UEBwwISGVsc2lua2kxIjAgBgNV +BAoMGUlOU0lERSBTZWN1cmUgQ29ycG9yYXRpb24xDTALBgNVBAsMBFRlc3QxMzAx +BgNVBAMMKlNhbXBsZSBNYXRyaXggRUMtNTIxIENlcnRpZmljYXRlIEF1dGhvcml0 +eTEhMB8GCSqGSIb3DQEJARYSdGVzdEBlbWFpbC5hZGRyZXNzMB4XDTE5MDEyOTEy +MDEwMVoXDTI5MDEyOTEyMDEwMVowgb0xCzAJBgNVBAYTAkZJMRAwDgYDVQQIDAdG +aW5sYW5kMREwDwYDVQQHDAhIZWxzaW5raTEiMCAGA1UECgwZSU5TSURFIFNlY3Vy +ZSBDb3Jwb3JhdGlvbjENMAsGA1UECwwEVGVzdDEzMDEGA1UEAwwqU2FtcGxlIE1h +dHJpeCBFQy01MjEgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkB +FhJ0ZXN0QGVtYWlsLmFkZHJlc3MwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAH0 +l63XWWqBn52Ebn03N00zDKIONOL+fsRZwNCDTs78fJ/ejdGJvhZKZGidnv7E0dD6 +iAUS2xM5Y/F5ND9EYEKqLQAzCj+5Wwf9fLdbhQpnB9/uQSvBfNvb/7gQnOpVwvo8 +WlnHfTBfH53yFLeK35jB37h+LPqnhEJAZekzIxh2keh1YKNmMGQwEgYDVR0TAQH/ +BAgwBgEB/wIBADAdBgNVHQ4EFgQUwYEYHnph8Y7px5OJ/p2g0/a6f2owHwYDVR0j +BBgwFoAUwYEYHnph8Y7px5OJ/p2g0/a6f2owDgYDVR0PAQH/BAQDAgAEMAoGCCqG +SM49BAMEA4GKADCBhgJBW2UbtukViDHJhC0rgp7Q9Efpr7IO1Q9LRA5cw6oh1l3a +6ugaDVtICXVnNDrUR2Cz7wT2TD4jJ9xYxUifrpg18MkCQR/c2HstdFkanVmni3hh +ZS7UMnFrI8dzdlDe0NbXU3QgCzN7PBcFZg1zR8ctlDGm2o0q8ByvfKCyEBHkpFIj +Mpl4 +-----END CERTIFICATE----- diff --git a/testkeys/EC/alt1/521_EC_CA_KEY.pem b/testkeys/EC/alt1/521_EC_CA_KEY.pem new file mode 100644 index 0000000..c54d7d2 --- /dev/null +++ b/testkeys/EC/alt1/521_EC_CA_KEY.pem @@ -0,0 +1,10 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBPp1VXHSpqlQyqd354BS2R7YKVmbi1IDPTZWG5i+JiU6PLr5J7+Ts +H6TZI5cOdCGyLCyijpTqCFT9DafuT31MwrugBwYFK4EEACOhgYkDgYYABAH0l63X +WWqBn52Ebn03N00zDKIONOL+fsRZwNCDTs78fJ/ejdGJvhZKZGidnv7E0dD6iAUS +2xM5Y/F5ND9EYEKqLQAzCj+5Wwf9fLdbhQpnB9/uQSvBfNvb/7gQnOpVwvo8WlnH +fTBfH53yFLeK35jB37h+LPqnhEJAZekzIxh2keh1YA== +-----END EC PRIVATE KEY----- diff --git a/testkeys/EC/alt1/521_EC_KEY.pem b/testkeys/EC/alt1/521_EC_KEY.pem new file mode 100644 index 0000000..ca69103 --- /dev/null +++ b/testkeys/EC/alt1/521_EC_KEY.pem @@ -0,0 +1,10 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBafcFZY/Kyr+wJaQE4OBj44rb8VjxXtR/L/HxbdUUvVC73s1dBM6f +DvG0QPJFAsLLB32crSCmGWiGxcmbilSnlhSgBwYFK4EEACOhgYkDgYYABAAga4T7 +4ZMwM3UNIG+CeJmXtH9FDLVdbN3VRjPJFTeUyu4UZ9320DEd3veUq4+ym3qO0xS1 +9jKIbXLzlYJcl5dP8wEGe84usY3LAyo+gLxK/pBSk/7hG9IxyyArydE7MoZueqeD +akR2dD/mS8XIFRLqGIyzODN2n6WCq2DpVe1twVk7dQ== +-----END EC PRIVATE KEY----- diff --git a/testkeys/PSK/tls13_psk.h b/testkeys/PSK/tls13_psk.h index f5bbc96..2439da4 100644 --- a/testkeys/PSK/tls13_psk.h +++ b/testkeys/PSK/tls13_psk.h @@ -5,7 +5,7 @@ * Example Pre-Shared Key header file to use with TLS 1.3. */ -/* Test SHA-256 based PSK to use in TLS 1.3. +/* Test SHA-256 based PSK for use in TLS 1.3. -psk 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 */ const static unsigned char g_tls13_test_psk_256[] = { @@ -14,6 +14,13 @@ const static unsigned char g_tls13_test_psk_256[] = 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 }; +const static unsigned char g_tls13_test_psk_id_sha256 [] = +{ + 'm', 'y', 'p', 's', 'k', 's', 'h', 'a', '2', '5', '6' +}; + +/* Test SHA-384 based PSK for use in TLS 1.3. + -psk 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30 */ const static unsigned char g_tls13_test_psk_384[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, @@ -23,8 +30,7 @@ const static unsigned char g_tls13_test_psk_384[] = 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, }; - -const static unsigned char g_tls13_test_psk_id [] = +const static unsigned char g_tls13_test_psk_id_sha384 [] = { - 'm', 'y', 'p', 's', 'k' + 'm', 'y', 'p', 's', 'k', 's', 'h', 'a', '3', '8', '4' }; diff --git a/testkeys/RSA/2048_RSA_PSS.h b/testkeys/RSA/2048_RSA_PSS.h new file mode 100644 index 0000000..8ead003 --- /dev/null +++ b/testkeys/RSA/2048_RSA_PSS.h @@ -0,0 +1,114 @@ +/** + * @file 2048_RSA_PSS.h + * + * Binary file for including certificate to MatrixSSL. + */ +static const unsigned char RSA_PSS2048[] = { + 0x30, 0x82, 0x04, 0xf0, 0x30, 0x82, 0x03, 0xa7, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x01, 0x30, 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, + 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, + 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, + 0x02, 0x01, 0xa2, 0x04, 0x02, 0x02, 0x00, 0xde, 0x30, 0x81, 0xc3, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x46, + 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, + 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x19, + 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, + 0x54, 0x65, 0x73, 0x74, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x30, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x4d, 0x61, + 0x74, 0x72, 0x69, 0x78, 0x20, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, 0x53, + 0x2d, 0x32, 0x30, 0x34, 0x38, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, + 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x33, 0x31, 0x34, + 0x31, 0x32, 0x30, 0x35, 0x30, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, + 0x33, 0x31, 0x34, 0x31, 0x32, 0x30, 0x35, 0x30, 0x37, 0x5a, 0x30, 0x81, + 0xb9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, + 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x48, 0x65, 0x6c, 0x73, 0x69, + 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x26, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, + 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x52, 0x53, 0x41, 0x5f, 0x50, + 0x53, 0x53, 0x2d, 0x32, 0x30, 0x34, 0x38, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, + 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x30, 0x82, 0x01, 0x20, 0x30, 0x0b, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x03, + 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0x9f, 0x14, 0xc9, 0xc0, 0x0f, 0x04, 0x6c, 0x65, 0x10, 0xc4, 0xd2, + 0xb6, 0x40, 0x3c, 0x90, 0x49, 0x79, 0x89, 0xcc, 0xcb, 0x7e, 0x33, 0x52, + 0xca, 0x77, 0x75, 0x0a, 0x15, 0xd2, 0x72, 0x9a, 0xd8, 0xc7, 0x5b, 0x2f, + 0x02, 0x5c, 0x12, 0x37, 0xe5, 0xc7, 0x20, 0xf7, 0x38, 0xa3, 0x55, 0xeb, + 0x35, 0xa0, 0x23, 0x12, 0xac, 0x81, 0x37, 0xe8, 0xac, 0x58, 0xc7, 0x7d, + 0xb9, 0x33, 0xdd, 0x51, 0x67, 0x26, 0x35, 0x3e, 0x6b, 0x5f, 0x09, 0x0c, + 0xa9, 0x7d, 0x6f, 0x06, 0x08, 0xb2, 0x05, 0xb8, 0x94, 0x1c, 0xb5, 0x6a, + 0x74, 0x49, 0x06, 0x15, 0xf7, 0xd9, 0x7b, 0x3d, 0x1f, 0x1f, 0xb6, 0x16, + 0xc9, 0xb1, 0xad, 0xd0, 0xbb, 0xbb, 0xee, 0xe8, 0xee, 0xce, 0x81, 0xf2, + 0x37, 0xb3, 0xb2, 0x16, 0xcd, 0x58, 0x1b, 0xd1, 0xfc, 0x50, 0x2b, 0x29, + 0x31, 0x3e, 0x9e, 0xb8, 0x4c, 0xd6, 0xc6, 0xd0, 0x1e, 0x3b, 0x80, 0x77, + 0xc1, 0xc6, 0x10, 0xcc, 0x7a, 0x5a, 0x88, 0x64, 0x71, 0x25, 0x51, 0x2e, + 0x92, 0xeb, 0x7f, 0x9e, 0x4a, 0x3c, 0x9b, 0x34, 0x5a, 0x8f, 0x42, 0x4e, + 0x63, 0xdd, 0xa0, 0xed, 0x98, 0x27, 0x8a, 0x91, 0x72, 0x4e, 0x4f, 0x69, + 0x6e, 0x8a, 0x0f, 0xb1, 0x65, 0x62, 0x37, 0xe8, 0x75, 0x17, 0x82, 0xa4, + 0x1d, 0xa8, 0x37, 0xe1, 0x5e, 0xdb, 0x99, 0x7b, 0xe9, 0x0a, 0x4b, 0x2a, + 0x9b, 0x5c, 0xb4, 0xed, 0x5e, 0x4f, 0x0e, 0xfc, 0x39, 0x57, 0xe8, 0x08, + 0x1d, 0x0b, 0x07, 0x5a, 0xd3, 0xe1, 0xb1, 0xe4, 0x88, 0x2d, 0x41, 0x8c, + 0xca, 0x56, 0xf0, 0xda, 0xb5, 0xf5, 0x20, 0x13, 0x8e, 0xc3, 0x7c, 0x81, + 0x43, 0x6f, 0xb8, 0xb2, 0x2a, 0x0e, 0x53, 0x22, 0xa4, 0x89, 0x0e, 0xd1, + 0x36, 0xe8, 0x0e, 0xea, 0x1a, 0x4d, 0x14, 0x36, 0x05, 0x26, 0x21, 0x49, + 0x27, 0x64, 0x4c, 0x54, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, + 0x96, 0x30, 0x81, 0x93, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, + 0x03, 0x02, 0x05, 0xe0, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, + 0x13, 0x30, 0x11, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, + 0x73, 0x74, 0x87, 0x04, 0x7f, 0x00, 0x00, 0x01, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x03, 0x02, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, + 0x04, 0x14, 0x3a, 0x01, 0xb4, 0x20, 0x1a, 0xf5, 0xc3, 0xfd, 0x9a, 0xd4, + 0xa4, 0x50, 0xb0, 0xda, 0x77, 0xea, 0xea, 0x07, 0x54, 0x45, 0x30, 0x1f, + 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x85, + 0x21, 0x1e, 0xcc, 0xe2, 0x4d, 0x51, 0xbe, 0xb4, 0x18, 0x74, 0x10, 0x23, + 0x02, 0xa9, 0xad, 0x38, 0xb4, 0x50, 0x19, 0x30, 0x3e, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x31, 0xa0, 0x0d, + 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04, 0x02, 0x02, 0x00, 0xde, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x6b, 0xce, 0xcc, 0xa4, 0x32, 0x8d, 0x1f, 0x38, + 0xfc, 0xde, 0x26, 0xa6, 0x13, 0x82, 0x46, 0x7d, 0x4d, 0x71, 0x5c, 0xc9, + 0xba, 0xe3, 0x57, 0x97, 0x3d, 0x82, 0x29, 0xc0, 0x72, 0xf0, 0x13, 0x82, + 0xfb, 0x36, 0x91, 0x5c, 0xf9, 0xe7, 0x78, 0x01, 0x98, 0x37, 0x4a, 0x75, + 0x3f, 0x90, 0x59, 0x33, 0x93, 0x53, 0x5c, 0xee, 0xe2, 0x08, 0xc4, 0xb3, + 0x98, 0x82, 0xed, 0x08, 0x65, 0x4b, 0x19, 0xa6, 0x7f, 0x3e, 0x2f, 0x2e, + 0x08, 0x10, 0x7d, 0xf5, 0x27, 0xba, 0x2d, 0x5b, 0x6e, 0xc3, 0x2b, 0x6f, + 0xba, 0x6b, 0x28, 0x4c, 0x31, 0x80, 0xac, 0xc7, 0xf7, 0x33, 0xe7, 0x49, + 0xc0, 0x96, 0x3b, 0x09, 0x6a, 0x66, 0x9a, 0x01, 0xeb, 0x1b, 0x0f, 0x8e, + 0x5c, 0xa2, 0xe8, 0x43, 0x6c, 0x81, 0x13, 0x2f, 0x67, 0xb5, 0x68, 0x1a, + 0x35, 0xe2, 0x45, 0x56, 0x9c, 0x17, 0xcd, 0x92, 0xec, 0xf8, 0xda, 0x3a, + 0xb5, 0xb1, 0x96, 0xc8, 0x8b, 0x9a, 0x5e, 0xf8, 0x26, 0x32, 0xca, 0x68, + 0x10, 0xe9, 0x96, 0x24, 0x65, 0x97, 0x4b, 0x82, 0xd7, 0x4b, 0x7b, 0x26, + 0x37, 0x3f, 0x9d, 0x36, 0x7a, 0x04, 0x88, 0x05, 0xd8, 0x07, 0x58, 0x50, + 0xee, 0xfe, 0x70, 0x45, 0xc2, 0x73, 0xdb, 0x83, 0x3c, 0xcd, 0x11, 0x9d, + 0x51, 0xa0, 0x04, 0x04, 0xb8, 0x00, 0x71, 0x58, 0x13, 0x0c, 0xb7, 0xcb, + 0xe8, 0x24, 0x33, 0x35, 0xdf, 0x69, 0x90, 0xc3, 0x1b, 0xf0, 0x50, 0x34, + 0x03, 0x38, 0xc9, 0xb2, 0x15, 0x1f, 0x85, 0x1a, 0xfe, 0xb7, 0x72, 0x8d, + 0xa8, 0xbe, 0xf4, 0x39, 0x3e, 0x03, 0xfe, 0xc3, 0xfe, 0xe7, 0x90, 0x2d, + 0x26, 0x7d, 0x56, 0xf2, 0xd1, 0x96, 0xf9, 0x20, 0xdc, 0xa0, 0x20, 0xe6, + 0x9a, 0x22, 0xba, 0x78, 0xfe, 0x27, 0x8a, 0xbb, 0x9b, 0x30, 0xb0, 0xd8, + 0x63, 0x7f, 0xa9, 0xb3, 0xf8, 0x17, 0x41, 0xbd +}; +#define RSA_PSS2048_SIZE 1268 diff --git a/testkeys/RSA/2048_RSA_PSS.pem b/testkeys/RSA/2048_RSA_PSS.pem new file mode 100644 index 0000000..f9a9315 --- /dev/null +++ b/testkeys/RSA/2048_RSA_PSS.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE8DCCA6egAwIBAgIBATA+BgkqhkiG9w0BAQowMaANMAsGCWCGSAFlAwQCAaEa +MBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiBAICAN4wgcMxCzAJBgNVBAYTAkZJ +MRAwDgYDVQQIDAdGaW5sYW5kMREwDwYDVQQHDAhIZWxzaW5raTEiMCAGA1UECgwZ +SU5TSURFIFNlY3VyZSBDb3Jwb3JhdGlvbjENMAsGA1UECwwEVGVzdDE5MDcGA1UE +AwwwU2FtcGxlIE1hdHJpeCBSU0FfUFNTLTIwNDggQ2VydGlmaWNhdGUgQXV0aG9y +aXR5MSEwHwYJKoZIhvcNAQkBFhJ0ZXN0QGVtYWlsLmFkZHJlc3MwHhcNMTkwMzE0 +MTIwNTA3WhcNMjkwMzE0MTIwNTA3WjCBuTELMAkGA1UEBhMCRkkxEDAOBgNVBAgM +B0ZpbmxhbmQxETAPBgNVBAcMCEhlbHNpbmtpMSIwIAYDVQQKDBlJTlNJREUgU2Vj +dXJlIENvcnBvcmF0aW9uMQ0wCwYDVQQLDARUZXN0MS8wLQYDVQQDDCZTYW1wbGUg +TWF0cml4IFJTQV9QU1MtMjA0OCBDZXJ0aWZpY2F0ZTEhMB8GCSqGSIb3DQEJARYS +dGVzdEBlbWFpbC5hZGRyZXNzMIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEB +AJ8UycAPBGxlEMTStkA8kEl5iczLfjNSynd1ChXScprYx1svAlwSN+XHIPc4o1Xr +NaAjEqyBN+isWMd9uTPdUWcmNT5rXwkMqX1vBgiyBbiUHLVqdEkGFffZez0fH7YW +ybGt0Lu77ujuzoHyN7OyFs1YG9H8UCspMT6euEzWxtAeO4B3wcYQzHpaiGRxJVEu +kut/nko8mzRaj0JOY92g7ZgnipFyTk9pbooPsWViN+h1F4KkHag34V7bmXvpCksq +m1y07V5PDvw5V+gIHQsHWtPhseSILUGMylbw2rX1IBOOw3yBQ2+4sioOUyKkiQ7R +NugO6hpNFDYFJiFJJ2RMVAsCAwEAAaOBljCBkzAJBgNVHRMEAjAAMAsGA1UdDwQE +AwIF4DAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwHQYDVR0lBBYwFAYIKwYB +BQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBQ6AbQgGvXD/ZrUpFCw2nfq6gdURTAf +BgNVHSMEGDAWgBSFIR7M4k1RvrQYdBAjAqmtOLRQGTA+BgkqhkiG9w0BAQowMaAN +MAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiBAICAN4D +ggEBAGvOzKQyjR84/N4mphOCRn1NcVzJuuNXlz2CKcBy8BOC+zaRXPnneAGYN0p1 +P5BZM5NTXO7iCMSzmILtCGVLGaZ/Pi8uCBB99Se6LVtuwytvumsoTDGArMf3M+dJ +wJY7CWpmmgHrGw+OXKLoQ2yBEy9ntWgaNeJFVpwXzZLs+No6tbGWyIuaXvgmMspo +EOmWJGWXS4LXS3smNz+dNnoEiAXYB1hQ7v5wRcJz24M8zRGdUaAEBLgAcVgTDLfL +6CQzNd9pkMMb8FA0AzjJshUfhRr+t3KNqL70OT4D/sP+55AtJn1W8tGW+SDcoCDm +miK6eP4nirubMLDYY3+ps/gXQb0= +-----END CERTIFICATE----- diff --git a/testkeys/RSA/2048_RSA_PSS_CA.h b/testkeys/RSA/2048_RSA_PSS_CA.h new file mode 100644 index 0000000..21638b4 --- /dev/null +++ b/testkeys/RSA/2048_RSA_PSS_CA.h @@ -0,0 +1,112 @@ +/** + * @file 2048_RSA_PSS_CA.h + * + * Binary file for including certificate to MatrixSSL. + */ +static const unsigned char RSA_PSS2048CA[] = { + 0x30, 0x82, 0x04, 0xdc, 0x30, 0x82, 0x03, 0x93, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x09, 0xd7, 0x56, 0x19, 0xfa, 0xda, 0xcc, 0xea, 0xfe, + 0xd3, 0xa5, 0x0c, 0x45, 0xd0, 0x15, 0xc0, 0x10, 0x9a, 0xc1, 0xa1, 0x30, + 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, + 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04, 0x02, + 0x02, 0x00, 0xde, 0x30, 0x81, 0xc3, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, + 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, + 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, 0x30, 0x20, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, 0x49, 0x44, + 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x6f, 0x72, + 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, 0x30, 0x0b, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, 0x74, 0x31, + 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x30, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, + 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, 0x53, 0x2d, 0x32, 0x30, 0x34, 0x38, + 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, + 0x01, 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x39, 0x30, 0x33, 0x31, 0x34, 0x31, 0x32, 0x30, 0x35, 0x30, + 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x33, 0x31, 0x34, 0x31, 0x32, + 0x30, 0x35, 0x30, 0x36, 0x5a, 0x30, 0x81, 0xc3, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x49, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x46, 0x69, 0x6e, 0x6c, + 0x61, 0x6e, 0x64, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x08, 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x31, 0x22, + 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x19, 0x49, 0x4e, 0x53, + 0x49, 0x44, 0x45, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, + 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x0d, + 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x04, 0x54, 0x65, 0x73, + 0x74, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x30, + 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, + 0x78, 0x20, 0x52, 0x53, 0x41, 0x5f, 0x50, 0x53, 0x53, 0x2d, 0x32, 0x30, + 0x34, 0x38, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x65, 0x73, 0x74, 0x40, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x2e, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x30, + 0x82, 0x01, 0x20, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0a, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, + 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa9, 0x5b, 0x85, 0x39, 0x40, 0x66, + 0x3b, 0x4f, 0xb1, 0x07, 0x9d, 0xe1, 0x7f, 0x12, 0x42, 0x51, 0xf7, 0xfb, + 0x81, 0xce, 0x66, 0x47, 0x0b, 0xf0, 0x8a, 0x63, 0x60, 0xd7, 0xf6, 0x59, + 0x49, 0xfb, 0x66, 0x0c, 0x80, 0x04, 0xa5, 0x14, 0x15, 0x38, 0x89, 0x7d, + 0x04, 0xed, 0x1a, 0xc8, 0x97, 0x73, 0x98, 0x36, 0x2c, 0xc3, 0xb2, 0xa3, + 0xa3, 0xdc, 0xd6, 0x5f, 0x79, 0x7f, 0xca, 0x34, 0xa5, 0x75, 0x7e, 0x6f, + 0x4d, 0x34, 0xdb, 0x1e, 0x3f, 0x9f, 0xb7, 0xd0, 0xb3, 0x05, 0xfb, 0x23, + 0xc2, 0x42, 0x7b, 0x97, 0x6f, 0xa9, 0xab, 0x49, 0x19, 0x7b, 0x38, 0x93, + 0xde, 0xc9, 0x1e, 0x12, 0xa0, 0x27, 0x6d, 0xd2, 0xa0, 0x95, 0xb4, 0x35, + 0x5c, 0xb0, 0xe4, 0xfe, 0x5a, 0xb9, 0x3c, 0xae, 0x24, 0x82, 0x14, 0x83, + 0x79, 0xaa, 0x58, 0xab, 0x75, 0x54, 0x60, 0x9d, 0xb3, 0x87, 0x6d, 0x03, + 0xac, 0x90, 0x23, 0xfb, 0xe1, 0x95, 0x7b, 0x89, 0xbe, 0xbd, 0xe7, 0x3f, + 0x99, 0x73, 0x1a, 0x9e, 0x26, 0xa6, 0xa3, 0x80, 0x8c, 0xe2, 0xa5, 0x42, + 0x35, 0x4d, 0x3f, 0xda, 0xe8, 0xc1, 0x02, 0x5d, 0x76, 0xd0, 0x56, 0x76, + 0xa5, 0x82, 0x7b, 0xb9, 0xc5, 0xa6, 0x6f, 0x4a, 0xb5, 0xc3, 0x35, 0x41, + 0xc8, 0x75, 0x99, 0x7c, 0x1b, 0x8f, 0x91, 0x2b, 0x66, 0x62, 0xd5, 0x56, + 0x10, 0xfd, 0x3f, 0x7c, 0x36, 0xc3, 0x55, 0xb8, 0xb8, 0xff, 0x0b, 0xf8, + 0x32, 0xb9, 0x6b, 0x53, 0xdb, 0xe9, 0xa2, 0x4e, 0x8e, 0x42, 0x90, 0x3a, + 0xe2, 0xc7, 0x74, 0x17, 0x0a, 0x41, 0x90, 0xd9, 0xa2, 0xed, 0x0a, 0x8d, + 0x2e, 0x84, 0xb7, 0x70, 0xa8, 0x69, 0xe5, 0x45, 0x05, 0xa7, 0x15, 0x3e, + 0xc1, 0x97, 0xe7, 0xc4, 0xbd, 0xe7, 0xc2, 0x09, 0x73, 0x14, 0x1a, 0x26, + 0xf6, 0x3f, 0xe3, 0x95, 0x46, 0xc1, 0xcf, 0x5a, 0xe4, 0x17, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, + 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, + 0x04, 0x14, 0x85, 0x21, 0x1e, 0xcc, 0xe2, 0x4d, 0x51, 0xbe, 0xb4, 0x18, + 0x74, 0x10, 0x23, 0x02, 0xa9, 0xad, 0x38, 0xb4, 0x50, 0x19, 0x30, 0x1f, + 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x85, + 0x21, 0x1e, 0xcc, 0xe2, 0x4d, 0x51, 0xbe, 0xb4, 0x18, 0x74, 0x10, 0x23, + 0x02, 0xa9, 0xad, 0x38, 0xb4, 0x50, 0x19, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x00, 0x04, 0x30, + 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, + 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04, 0x02, + 0x02, 0x00, 0xde, 0x03, 0x82, 0x01, 0x01, 0x00, 0x88, 0x7b, 0xc8, 0x87, + 0x7f, 0x2b, 0x07, 0x6b, 0xa5, 0x6e, 0x35, 0xef, 0x51, 0xb9, 0xdc, 0xe0, + 0xa5, 0x46, 0x22, 0xdc, 0x3e, 0xe6, 0xd7, 0x31, 0x59, 0x42, 0xcc, 0x42, + 0x08, 0xa3, 0xf1, 0x13, 0x55, 0x92, 0x9b, 0xb6, 0xba, 0xc9, 0x1a, 0xb7, + 0xb8, 0xed, 0x5c, 0xf3, 0xe9, 0xa3, 0x49, 0xcd, 0xee, 0x4a, 0x0d, 0x8f, + 0x22, 0x92, 0x54, 0xd6, 0xa0, 0x6a, 0x28, 0x46, 0xd1, 0x16, 0x7a, 0x84, + 0xf2, 0x05, 0x29, 0x6c, 0x19, 0xc3, 0x5f, 0x49, 0x75, 0x66, 0x35, 0x3f, + 0x5e, 0x31, 0xeb, 0x9a, 0x8b, 0x74, 0xb7, 0x04, 0x40, 0xac, 0x1b, 0x77, + 0x5d, 0x30, 0x35, 0xff, 0x83, 0x29, 0x38, 0xfe, 0xa1, 0xbc, 0xab, 0x42, + 0x86, 0xe5, 0x09, 0x2e, 0x09, 0xd6, 0xa0, 0xa8, 0xca, 0x8c, 0x66, 0x5b, + 0xa8, 0xf7, 0x8e, 0x18, 0x00, 0x7b, 0xd7, 0x58, 0xba, 0x98, 0x84, 0x2b, + 0x99, 0xca, 0x40, 0xa6, 0xd5, 0x46, 0xfe, 0x32, 0x50, 0xb4, 0x74, 0x22, + 0xdf, 0x96, 0x29, 0xf7, 0x85, 0xdb, 0x14, 0xaf, 0x92, 0xa2, 0x49, 0x21, + 0x01, 0xbd, 0x68, 0x68, 0xb6, 0xd4, 0xc0, 0x46, 0x88, 0x69, 0xd2, 0xdb, + 0xb7, 0x3b, 0x06, 0x78, 0x52, 0xad, 0x66, 0x9e, 0xf6, 0x6f, 0x4c, 0x06, + 0xbe, 0xd6, 0xda, 0x59, 0xd6, 0x99, 0xaa, 0x62, 0x5d, 0x06, 0xe5, 0x11, + 0x04, 0x45, 0x5a, 0x83, 0x14, 0x81, 0xf1, 0xae, 0x3d, 0x56, 0xe2, 0x59, + 0xf9, 0x97, 0x00, 0x20, 0x26, 0xd0, 0xbb, 0xfe, 0x12, 0x7e, 0x12, 0x3d, + 0x6b, 0x20, 0xb7, 0xb1, 0xfe, 0x92, 0x4d, 0x94, 0x13, 0x7e, 0xce, 0x64, + 0x01, 0x5a, 0x17, 0xda, 0xb3, 0x30, 0x30, 0x14, 0x6d, 0x60, 0x46, 0xf8, + 0xf8, 0x0b, 0x22, 0x43, 0x5c, 0x44, 0x85, 0x6c, 0x63, 0x77, 0xfd, 0xb4, + 0x97, 0x61, 0xb0, 0x41, 0xdc, 0x54, 0xcd, 0xa5, 0x1c, 0x24, 0xad, 0x49 +}; +#define RSA_PSS2048CA_SIZE 1248 diff --git a/testkeys/RSA/2048_RSA_PSS_CA.pem b/testkeys/RSA/2048_RSA_PSS_CA.pem new file mode 100644 index 0000000..d641c99 --- /dev/null +++ b/testkeys/RSA/2048_RSA_PSS_CA.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIE3DCCA5OgAwIBAgIUCddWGfrazOr+06UMRdAVwBCawaEwPgYJKoZIhvcNAQEK +MDGgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQC +AgDeMIHDMQswCQYDVQQGEwJGSTEQMA4GA1UECAwHRmlubGFuZDERMA8GA1UEBwwI +SGVsc2lua2kxIjAgBgNVBAoMGUlOU0lERSBTZWN1cmUgQ29ycG9yYXRpb24xDTAL +BgNVBAsMBFRlc3QxOTA3BgNVBAMMMFNhbXBsZSBNYXRyaXggUlNBX1BTUy0yMDQ4 +IENlcnRpZmljYXRlIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSdGVzdEBlbWFp +bC5hZGRyZXNzMB4XDTE5MDMxNDEyMDUwNloXDTI5MDMxNDEyMDUwNlowgcMxCzAJ +BgNVBAYTAkZJMRAwDgYDVQQIDAdGaW5sYW5kMREwDwYDVQQHDAhIZWxzaW5raTEi +MCAGA1UECgwZSU5TSURFIFNlY3VyZSBDb3Jwb3JhdGlvbjENMAsGA1UECwwEVGVz +dDE5MDcGA1UEAwwwU2FtcGxlIE1hdHJpeCBSU0FfUFNTLTIwNDggQ2VydGlmaWNh +dGUgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJ0ZXN0QGVtYWlsLmFkZHJlc3Mw +ggEgMAsGCSqGSIb3DQEBCgOCAQ8AMIIBCgKCAQEAqVuFOUBmO0+xB53hfxJCUff7 +gc5mRwvwimNg1/ZZSftmDIAEpRQVOIl9BO0ayJdzmDYsw7Kjo9zWX3l/yjSldX5v +TTTbHj+ft9CzBfsjwkJ7l2+pq0kZeziT3skeEqAnbdKglbQ1XLDk/lq5PK4kghSD +eapYq3VUYJ2zh20DrJAj++GVe4m+vec/mXManiamo4CM4qVCNU0/2ujBAl120FZ2 +pYJ7ucWmb0q1wzVByHWZfBuPkStmYtVWEP0/fDbDVbi4/wv4MrlrU9vpok6OQpA6 +4sd0FwpBkNmi7QqNLoS3cKhp5UUFpxU+wZfnxL3nwglzFBom9j/jlUbBz1rkFwID +AQABo2YwZDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSFIR7M4k1RvrQY +dBAjAqmtOLRQGTAfBgNVHSMEGDAWgBSFIR7M4k1RvrQYdBAjAqmtOLRQGTAOBgNV +HQ8BAf8EBAMCAAQwPgYJKoZIhvcNAQEKMDGgDTALBglghkgBZQMEAgGhGjAYBgkq +hkiG9w0BAQgwCwYJYIZIAWUDBAIBogQCAgDeA4IBAQCIe8iHfysHa6VuNe9Rudzg +pUYi3D7m1zFZQsxCCKPxE1WSm7a6yRq3uO1c8+mjSc3uSg2PIpJU1qBqKEbRFnqE +8gUpbBnDX0l1ZjU/XjHrmot0twRArBt3XTA1/4MpOP6hvKtChuUJLgnWoKjKjGZb +qPeOGAB711i6mIQrmcpAptVG/jJQtHQi35Yp94XbFK+SokkhAb1oaLbUwEaIadLb +tzsGeFKtZp72b0wGvtbaWdaZqmJdBuURBEVagxSB8a49VuJZ+ZcAICbQu/4SfhI9 +ayC3sf6STZQTfs5kAVoX2rMwMBRtYEb4+AsiQ1xEhWxjd/20l2GwQdxUzaUcJK1J +-----END CERTIFICATE----- diff --git a/testkeys/RSA/2048_RSA_PSS_CA_KEY.pem b/testkeys/RSA/2048_RSA_PSS_CA_KEY.pem new file mode 100644 index 0000000..9ca03bd --- /dev/null +++ b/testkeys/RSA/2048_RSA_PSS_CA_KEY.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuwIBADALBgkqhkiG9w0BAQoEggSnMIIEowIBAAKCAQEAqVuFOUBmO0+xB53h +fxJCUff7gc5mRwvwimNg1/ZZSftmDIAEpRQVOIl9BO0ayJdzmDYsw7Kjo9zWX3l/ +yjSldX5vTTTbHj+ft9CzBfsjwkJ7l2+pq0kZeziT3skeEqAnbdKglbQ1XLDk/lq5 +PK4kghSDeapYq3VUYJ2zh20DrJAj++GVe4m+vec/mXManiamo4CM4qVCNU0/2ujB +Al120FZ2pYJ7ucWmb0q1wzVByHWZfBuPkStmYtVWEP0/fDbDVbi4/wv4MrlrU9vp +ok6OQpA64sd0FwpBkNmi7QqNLoS3cKhp5UUFpxU+wZfnxL3nwglzFBom9j/jlUbB +z1rkFwIDAQABAoIBAH1ksgNt10PbAWxuTWPUlR4zyhiWRcwc3wDYDABa+kl4xlpC +/y1q7TtrMRHQrKAQ4xm0IvjS766H+IHAaAnDaS7Ran9zvzlqSkvDTooDJLrUlsXN +e4bDHQbLIVE2//kyc38xEI1HXKtAnoxlh/mRxp45qg8PPY/V05+lpCOFZ87/xgxo +ANL0VPTAMaUoUJqmVN4MJGWsaBRkkBC00nHwe6g51ZJk3tj0NUDsfe2wFSaB8d4q +PZf6sUHiIF1VhvL4bDNKzdW1Fn23swhP0lb4Sx/2ss4v1SbiyVRLf2vaILH0ymtr +tLsXONrZeBU3X1pzTDqFocBVXyqLS6a1+GFaIoECgYEA0YzgR+RZlheWRwWhrKT2 +m/rzHXBSSKMCI3T6uxKjM+Ex8IZYxEMdGT6DXnVqR9eaKkgGz4mHj7kBEWzFQdGU +a3AloGa/M1l4LN0kQO5TxjQct+t0mahY5BCk8emDrfu1l3MamJUQbxvWQvULqFuK +gGzPCIPQqO0hPhxCuss6rtECgYEAzuXeAy/iDqUmScZD0cZVzCDa6ZoevF5gcZAh +ijzHt3tn+wfqbB3HGNKmd/sZ0rfHR3HkG+vowRfXly2RYau8HUuc1vZG7CCn3R2g +c+5Qvm6g/rWNi0guJVnF4Z4I15Rx06jw5S1y9/yJGlIh6ClkfwA3NQlA/Y+uJ/EV +QJFFLmcCgYAmhc91Z/VQMmXeCJsAMhNj+W5YKx31XII4Ink1iueV0gBsR0ZqTiw7 +R9K+urcfHfOpcjROUuoo8cnQej6JKw4t8h/4rOrZdckx9jWD+kxMU6gz54U3+krd +InIwRs1+Xpezj+WDx2OOCYAKLyJFgQ6lLVuiJRlm9LD3yho6XMIdAQKBgQClU7fJ +kiywiTWEREMTUMpkeGiVvIsM+NlWRdcXUKRCsQEQ7m1bgZwD8OgG/gbPg/1g0Nh3 +m1Z9XeDvtAD1LDcArdghSeC4dQvOPAtoOCobUemiP09g2gfN3uOp+w+TvNIMUXZV +m7DACvM/rhvcGZ9tgK2c2s0tEPAYiKPz2WGPxwKBgDecFYGriUn8hAZHu3B2H67k +txbWpMKOKCSv9AaFbg9Rt3E+fHLOlN2zZE3DS+EpKjpH7IclDkDI8CyR3IsVjLlm +qcpRXtLhxXVbgTr1qoV413+gXyUr8uYAhd3599bqdIaIcnTLXeH0otdhNOqHHH2e +EJk8p4b8y+VwSvb1VL4D +-----END PRIVATE KEY----- diff --git a/testkeys/RSA/2048_RSA_PSS_KEY.pem b/testkeys/RSA/2048_RSA_PSS_KEY.pem new file mode 100644 index 0000000..b231a4f --- /dev/null +++ b/testkeys/RSA/2048_RSA_PSS_KEY.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuwIBADALBgkqhkiG9w0BAQoEggSnMIIEowIBAAKCAQEAnxTJwA8EbGUQxNK2 +QDyQSXmJzMt+M1LKd3UKFdJymtjHWy8CXBI35ccg9zijVes1oCMSrIE36KxYx325 +M91RZyY1PmtfCQypfW8GCLIFuJQctWp0SQYV99l7PR8fthbJsa3Qu7vu6O7OgfI3 +s7IWzVgb0fxQKykxPp64TNbG0B47gHfBxhDMelqIZHElUS6S63+eSjybNFqPQk5j +3aDtmCeKkXJOT2luig+xZWI36HUXgqQdqDfhXtuZe+kKSyqbXLTtXk8O/DlX6Agd +Cwda0+Gx5IgtQYzKVvDatfUgE47DfIFDb7iyKg5TIqSJDtE26A7qGk0UNgUmIUkn +ZExUCwIDAQABAoIBAEkOUey6uMxSyZWqMvpjFdw4TZlYZpeJUOP1QvFsmScVoM/2 +Ub4Yu8TxYulGAHTHtPPax4ujOBrJc2gCC9iOrgCR4mfNBXLxdrDdGMdLgicXFewW +fFrAybvuC5OxRG3qHyxS54Yfs4MTkJDKvNvwUFpzOSuBFQwNOclJONhI1jrivfV9 +8WCL0IDo42ycUYglvOxDfMp6JpC+O8+Ke0/+K8Pi+ehADdwfQ+0AFH0vdbY7LeGs +B5eo1EdV0m93e46eHFjrlQf1lMZ9aKGl+W1oMTzrZ7Z40SY4AtZEyp1zFtASsvdu +NZDjXAe+qce1LLPaV6FCqud+9FXHX7fHTPuw8VkCgYEA0SrrKq7Uii2srv+hPibw +A57yAR/vUM/6pGlTkZtR3O1cMLPC7E7IFnGQuRHoJ5gKtxAvgTwFQXdNSGRthwy5 +UbGKWlPqwDJgnd7zUhQCymhoIfZUyQQL8dWuOr9OxCbwRLKvLM/jUHU1fIfeVZqc +inWB+GeWjRopnuMSapq6nF8CgYEAwrMDGDSCxZs8Uaumn3t/j4uybTw1CkR87z88 +ALSQRdqIAO1T4EuovDuKOkLSpPKY3mCPXA/JbM7/rQmM9TrOC024ytNjTmwPSmMv +1QyxpNDb4DFKTQ2UgJG7D1Y3InUf9lHYK4oThHgIbrYR37a6vzb29ZwA7gGRiCbf +qCKiZ9UCgYEAtjOspoGkorkms0n6Kym/6WeLZ29qB/sjWhRlt3CU3t3kcIgmQ7Jc +mTBT4OK4V8UZkF2JBApEicJij6zru7hZtc/xtL1kwAciImMTkWvdAnPwQaVSNchQ +n1iDbKk486T3pt//uAle+bcf4Fp6UhdcRUAW90tE2aTwnHcwk6w04gECgYAm6LFg +n/XWWbyHMb99tad7X1aL//E1mRRCl6d9GJiQbSiqzsLpWxVgcKGiHQKNljG4lyFv +K3R8ey2bPgJea58LoT+hwPbikDPKEOJZOE0z+81FE3Sey2z2+KiiWv9vsmptxlNl ++BUIbxh4T4ho5dKSLgDSepew+L1FsUcXCbzc9QKBgD9tDf66hkkcOyF+xyNSq2ya +Il+iVYtdzYYPR8vu4ihwBtpF3Mw0tRCsFHkfwouBx+2h8fK7TgPN+7ad20c1OzKu +CbPxpMZofRxnffxG/okx+w58pU5xcVzBIXO5cmxl5XHgRGNqWE508/faijfvT9X/ ++MNvfJ34SDXg5H5/m1Oi +-----END PRIVATE KEY-----