Push an error if custom private keys fail.

The private key callback may not push one of its own (it's possible to
register a custom error library and whatnot, but this is tedious). If
the callback does not push any, we report SSL_ERROR_SYSCALL. This is not
completely wrong, as "syscall" really means "I don't know, something you
gave me, probably the BIO, failed so I assume you know what happened",
but most callers just check errno. And indeed cert_cb pushes its own
error, so this probably should as well.

Update-Note: Custom private key callbacks which push an error code on
    failure will report both that error followed by
    SSL_R_PRIVATE_KEY_OPERATION_FAILED. Callbacks which did not push any
    error will switch from SSL_ERROR_SYSCALL to SSL_ERROR_SSL with
    SSL_R_PRIVATE_KEY_OPERATION_FAILED.

Change-Id: I7e90cd327fe0cbcff395470381a3591364a82c74
Reviewed-on: https://boringssl-review.googlesource.com/25544
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2018-02-01 15:07:30 -05:00 committed by Adam Langley
parent 48669209b7
commit fa65113400
3 changed files with 8 additions and 0 deletions

View File

@ -117,6 +117,7 @@ SSL,191,PATH_TOO_LONG
SSL,192,PEER_DID_NOT_RETURN_A_CERTIFICATE
SSL,193,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
SSL,267,PRE_SHARED_KEY_MUST_BE_LAST
SSL,287,PRIVATE_KEY_OPERATION_FAILED
SSL,194,PROTOCOL_IS_SHUTDOWN
SSL,271,PSK_IDENTITY_BINDER_COUNT_MISMATCH
SSL,195,PSK_IDENTITY_NOT_FOUND

View File

@ -4697,6 +4697,7 @@ OPENSSL_EXPORT bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback);
#define SSL_R_HANDSHAKE_NOT_COMPLETE 284
#define SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI 285
#define SSL_R_SERVER_ECHOED_INVALID_SESSION_ID 286
#define SSL_R_PRIVATE_KEY_OPERATION_FAILED 287
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020

View File

@ -205,6 +205,9 @@ enum ssl_private_key_result_t ssl_private_key_sign(
ret = ssl->cert->key_method->sign(ssl, out, out_len, max_out, sigalg,
in.data(), in.size());
}
if (ret == ssl_private_key_failure) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
}
hs->pending_private_key_op = ret == ssl_private_key_retry;
return ret;
}
@ -241,6 +244,9 @@ enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out,
in.data(), in.size());
}
if (ret == ssl_private_key_failure) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED);
}
hs->pending_private_key_op = ret == ssl_private_key_retry;
return ret;
}