Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Unified Diff: runtime/bin/secure_socket.cc

Issue 1689873003: Fix PEM error checking (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Remove unused field from SSLFilter Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | tests/standalone/io/security_context_argument_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/secure_socket.cc
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index 2e0bb880c6742535f6b3afab345966bcc09de1e0..d7735afc088b8530fd2a27183164c7fb36512a2f 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -508,6 +508,18 @@ typedef ScopedSSLStackType<STACK_OF(X509), X509, X509_free> ScopedX509Stack;
typedef ScopedSSLStackType<STACK_OF(X509_NAME), X509_NAME, X509_NAME_free>
ScopedX509NAMEStack;
+
+// We try reading data as PKCS12 only if reading as PEM was unsuccessful and
+// if there is no indication that the data is malformed PEM. We assume the data
+// is malformed PEM if it contains the start line, i.e. a line with ----- BEGIN.
+static bool TryPKCS12(bool pem_success) {
+ uint32_t last_error = ERR_peek_last_error();
+ return !pem_success &&
+ (ERR_GET_LIB(last_error) == ERR_LIB_PEM) &&
+ (ERR_GET_REASON(last_error) == PEM_R_NO_START_LINE);
+}
+
+
static EVP_PKEY* GetPrivateKeyPKCS12(BIO* bio, const char* password) {
ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
if (p12.get() == NULL) {
@@ -532,12 +544,7 @@ static EVP_PKEY* GetPrivateKeyPKCS12(BIO* bio, const char* password) {
static EVP_PKEY* GetPrivateKey(BIO* bio, const char* password) {
EVP_PKEY *key = PEM_read_bio_PrivateKey(
bio, NULL, PasswordCallback, const_cast<char*>(password));
-
- // If the data doesn't contain the PEM start line, try reading as PKCS12.
- uint32_t err = ERR_peek_last_error();
- if ((key == NULL) &&
- (ERR_GET_LIB(err) == ERR_LIB_PEM) &&
- (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
+ if (TryPKCS12(key != NULL)) {
// Reset the bio, and clear the error from trying to read as PEM.
ERR_clear_error();
BIO_reset(bio);
@@ -641,10 +648,13 @@ static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) {
}
}
+ // If bio does not contain PEM data, the first call to PEM_read_bio_X509 will
+ // return NULL, and the while-loop will exit while status is still 0.
uint32_t err = ERR_peek_last_error();
if ((ERR_GET_LIB(err) != ERR_LIB_PEM) ||
(ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) {
- // Some real error happened.
+ // If bio contains data that is trying to be PEM but is malformed, then
+ // this case will be triggered.
status = 0;
}
@@ -654,10 +664,7 @@ static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) {
static int SetTrustedCertificatesBytes(SSL_CTX* context, BIO* bio) {
int status = SetTrustedCertificatesBytesPEM(context, bio);
- uint32_t err = ERR_peek_last_error();
- if ((status == 0) &&
- (ERR_GET_LIB(err) == ERR_LIB_PEM) &&
- (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
+ if (TryPKCS12(status != 0)) {
ERR_clear_error();
BIO_reset(bio);
status = SetTrustedCertificatesBytesPKCS12(context, bio);
@@ -780,10 +787,13 @@ static int UseChainBytesPEM(SSL_CTX* context, BIO* bio) {
// count is increased by SSL_CTX_use_certificate.
}
+ // If bio does not contain PEM data, the first call to PEM_read_bio_X509 will
+ // return NULL, and the while-loop will exit while status is still 0.
uint32_t err = ERR_peek_last_error();
if ((ERR_GET_LIB(err) != ERR_LIB_PEM) ||
(ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) {
- // Some real error happened.
+ // If bio contains data that is trying to be PEM but is malformed, then
+ // this case will be triggered.
status = 0;
}
@@ -793,15 +803,12 @@ static int UseChainBytesPEM(SSL_CTX* context, BIO* bio) {
static int UseChainBytes(SSL_CTX* context, BIO* bio) {
int status = UseChainBytesPEM(context, bio);
- uint32_t err = ERR_peek_last_error();
- if ((status == 0) &&
- (ERR_GET_LIB(err) == ERR_LIB_PEM) &&
- (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
+ if (TryPKCS12(status != 0)) {
ERR_clear_error();
BIO_reset(bio);
status = UseChainBytesPKCS12(context, bio);
} else if (status != 0) {
- // The PEM file was successfully parsed.
+ // The PEM file was successfully read.
ERR_clear_error();
}
return status;
@@ -912,10 +919,15 @@ static STACK_OF(X509_NAME)* GetCertificateNamesPEM(BIO* bio) {
sk_X509_NAME_push(result.get(), x509_name);
}
+ if (sk_X509_NAME_num(result.get()) == 0) {
+ // The data was not PEM.
+ return NULL;
+ }
+
uint32_t err = ERR_peek_last_error();
if ((ERR_GET_LIB(err) != ERR_LIB_PEM) ||
(ERR_GET_REASON(err) != PEM_R_NO_START_LINE)) {
- // Some real error happened.
+ // The data was trying to be PEM, but was malformed.
return NULL;
}
@@ -925,10 +937,7 @@ static STACK_OF(X509_NAME)* GetCertificateNamesPEM(BIO* bio) {
static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio) {
STACK_OF(X509_NAME)* result = GetCertificateNamesPEM(bio);
- uint32_t err = ERR_peek_last_error();
- if ((result == NULL) &&
- (ERR_GET_LIB(err) == ERR_LIB_PEM) &&
- (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
+ if (TryPKCS12(result != NULL)) {
ERR_clear_error();
BIO_reset(bio);
result = GetCertificateNamesPKCS12(bio);
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | tests/standalone/io/security_context_argument_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698