Skip to content

Commit

Permalink
Clear matching cert data when chain verification fails.
Browse files Browse the repository at this point in the history
Callers need to check that chain verification is successful before
checking for a matching certificate.  This protects lazy callers
that check only for a matching cert.
  • Loading branch information
Viktor Dukhovni committed Aug 26, 2015
1 parent 10791cd commit 8af5bf5
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
24 changes: 13 additions & 11 deletions Danessl/Danessl.xs
Original file line number Diff line number Diff line change
Expand Up @@ -440,11 +440,12 @@ verify(uarg, sarg, m, d, ...)
if (chain) {
xs = load_chain(chain);
SSL_set_connect_state(ssl);
ssl_verify_cert_chain(ssl, xs);
if (DANESSL_get_match_cert(ssl, 0, &mhost, &mdepth)) {
EXTEND(SP, 2);
mXPUSHi(mdepth);
mXPUSHs(newSVpv(mhost, 0));
if (ssl_verify_cert_chain(ssl, xs)) {
if (DANESSL_get_match_cert(ssl, 0, &mhost, &mdepth)) {
EXTEND(SP, 2);
mXPUSHi(mdepth);
mXPUSHs(newSVpv(mhost, 0));
}
} else {
long err = SSL_get_verify_result(ssl);
const char *reason = X509_verify_cert_error_string(err);
Expand Down Expand Up @@ -545,13 +546,14 @@ tlsagen(chain, dptharg, base, uarg, sarg, m)
croak("error processing TLSA RR\n");

SSL_set_connect_state(ssl);
ssl_verify_cert_chain(ssl, xs);

if (DANESSL_get_match_cert(ssl, 0, &mhost, &mdepth)) {
EXTEND(SP, 3);
mXPUSHi(mdepth);
mXPUSHs(newSVpv(mhost, 0));
mXPUSHs(newSVpv(d, 0));
if (ssl_verify_cert_chain(ssl, xs)) {
if (DANESSL_get_match_cert(ssl, 0, &mhost, &mdepth)) {
EXTEND(SP, 3);
mXPUSHi(mdepth);
mXPUSHs(newSVpv(mhost, 0));
mXPUSHs(newSVpv(d, 0));
}
} else {
long err = SSL_get_verify_result(ssl);
const char *reason = X509_verify_cert_error_string(err);
Expand Down
18 changes: 17 additions & 1 deletion danessl.c
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,23 @@ static int verify_cert(X509_STORE_CTX *ctx, void *unused_ctx)
dane->verify = ctx->verify;
ctx->verify = verify_chain;

return X509_verify_cert(ctx);
if (X509_verify_cert(ctx))
return 1;

/*
* If the chain is invalid, clear any matching cert or hostname, to
* protect callers that might erroneously rely on these alone without
* checking the validation status.
*/
if (dane->match) {
X509_free(dane->match);
dane->match = 0;
}
if (dane->mhost) {
OPENSSL_free(dane->mhost);
dane->mhost = 0;
}
return 0;
}

static dane_list list_alloc(size_t vsize)
Expand Down

0 comments on commit 8af5bf5

Please sign in to comment.