Skip to content

Commit 9eaeca3

Browse files
committed
Postpone freeing of X509 context to the first data exchange after handshake
X509 context contains certificate fingerprint and various names which may be used to verify the certificate. Previously we would free it right after the handshake completion, which prevented the client from actually using any information from X509 context. Postponing this to the first ssl_read/ssl_write call after the handshake, we give the client a chance to verify the certificate. Also added logging to ssl_match_fingerprint function in case fingerprint doesn't match expected value.
1 parent 28869ea commit 9eaeca3

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

ssl/tls1.c

+27-5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ static int set_key_block(SSL *ssl, int is_write);
5252
static int verify_digest(SSL *ssl, int mode, const uint8_t *buf, int read_len);
5353
static void *crypt_new(SSL *ssl, uint8_t *key, uint8_t *iv, int is_decrypt, void* cached);
5454
static int send_raw_packet(SSL *ssl, uint8_t protocol);
55+
static void certificate_free(SSL* ssl);
5556

5657
/**
5758
* The server will pick the cipher based on the order that the order that the
@@ -247,8 +248,8 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl)
247248
free(ssl->encrypt_ctx);
248249
free(ssl->decrypt_ctx);
249250
disposable_free(ssl);
251+
certificate_free(ssl);
250252
free(ssl->bm_all_data);
251-
free(ssl->fingerprint);
252253
free(ssl);
253254
}
254255

@@ -257,6 +258,9 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl)
257258
*/
258259
EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
259260
{
261+
if (ssl->hs_status == SSL_OK) {
262+
certificate_free(ssl);
263+
}
260264
int ret = basic_read(ssl, in_data);
261265

262266
/* check for return code so we can send an alert */
@@ -281,7 +285,9 @@ EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data)
281285
EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len)
282286
{
283287
int n = out_len, nw, i, tot = 0;
284-
288+
if (ssl->hs_status == SSL_OK) {
289+
certificate_free(ssl);
290+
}
285291
/* maximum size of a TLS packet is around 16kB, so fragment */
286292
do
287293
{
@@ -547,7 +553,6 @@ SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd)
547553
ssl->ca_cert_ctx = ssl_ctx->ca_cert_ctx;
548554
#endif
549555
disposable_new(ssl);
550-
ssl->fingerprint = 0;
551556

552557
/* a bit hacky but saves a few bytes of memory */
553558
ssl->flag |= ssl_ctx->options;
@@ -1671,12 +1676,17 @@ void disposable_free(SSL *ssl)
16711676
free(ssl->dc);
16721677
ssl->dc = NULL;
16731678
}
1679+
}
1680+
1681+
static void certificate_free(SSL* ssl)
1682+
{
16741683
#ifdef CONFIG_SSL_CERT_VERIFICATION
16751684
if (ssl->x509_ctx) {
16761685
x509_free(ssl->x509_ctx);
16771686
ssl->x509_ctx = 0;
16781687
}
16791688
#endif
1689+
increase_bm_data_size(ssl);
16801690
}
16811691

16821692
#ifndef CONFIG_SSL_SKELETON_MODE /* no session resumption in this mode */
@@ -1945,9 +1955,21 @@ int process_certificate(SSL *ssl, X509_CTX **x509_ctx)
19451955

19461956
EXP_FUNC int STDCALL ssl_match_fingerprint(const SSL *ssl, const uint8_t* fp)
19471957
{
1948-
if (!ssl->fingerprint)
1958+
if (ssl->x509_ctx == NULL || ssl->x509_ctx->fingerprint == NULL)
19491959
return 1;
1950-
return memcmp(ssl->fingerprint, fp, SHA1_SIZE);
1960+
int res = memcmp(ssl->x509_ctx->fingerprint, fp, SHA1_SIZE);
1961+
if (res != 0) {
1962+
printf("cert FP: ");
1963+
for (int i = 0; i < SHA1_SIZE; ++i) {
1964+
printf("%02X ", ssl->x509_ctx->fingerprint[i]);
1965+
}
1966+
printf("\r\ntest FP: ");
1967+
for (int i = 0; i < SHA1_SIZE; ++i) {
1968+
printf("%02X ", fp[i]);
1969+
}
1970+
printf("\r\n");
1971+
}
1972+
return res;
19511973
}
19521974

19531975
#endif /* CONFIG_SSL_CERT_VERIFICATION */

ssl/tls1.h

-2
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,6 @@ struct _SSL
190190
#ifdef CONFIG_SSL_CERT_VERIFICATION
191191
X509_CTX *x509_ctx;
192192
#endif
193-
uint8_t* fingerprint;
194-
195193
uint8_t session_id[SSL_SESSION_ID_SIZE];
196194
uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */
197195
uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */

ssl/tls1_clnt.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,7 @@ int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len)
119119

120120
case HS_FINISHED:
121121
ret = process_finished(ssl, buf, hs_len);
122-
ssl->fingerprint = ssl->x509_ctx->fingerprint;
123-
ssl->x509_ctx->fingerprint = 0;
124-
disposable_free(ssl); /* free up some memory */
125-
increase_bm_data_size(ssl);
122+
disposable_free(ssl);
126123
/* note: client renegotiation is not allowed after this */
127124
break;
128125

0 commit comments

Comments
 (0)