diff --git a/include/polarssl/pem.h b/include/polarssl/pem.h index 782b235d9..cc6cba14e 100644 --- a/include/polarssl/pem.h +++ b/include/polarssl/pem.h @@ -84,8 +84,9 @@ void pem_init( pem_context *ctx ); * POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is * the length to skip) * - * \note Checks password correctness by verifying if the decrypted - * text looks like a RSAPrivateKey or ECPrivateKey structure + * \note Attempts to check password correctness by verifying if + * the decrypted text starts with an ASN.1 sequence of + * appropriate length * * \return 0 on success, ior a specific PEM error code */ diff --git a/library/pem.c b/library/pem.c index 3e3e96df3..3f6d330a6 100644 --- a/library/pem.c +++ b/library/pem.c @@ -333,21 +333,12 @@ int pem_read_buffer( pem_context *ctx, const char *header, const char *footer, #endif /* POLARSSL_AES_C */ /* - * The result should look like RSAPrivateKey or ECPrivateKey - * We use the following heuristic: - * len must be more than 6 - * byte 1 must be 0x30 (SEQUENCE tag) - * then allow for one to 3 length bytes - * then we must have 0x02 0x01 (INTEGER tag + length, for version) - * version must be less than 4 (leaves some room) + * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 + * length bytes (allow 4 to be sure) in all known use cases. + * + * Use that as heurisitic to try detecting password mismatchs. */ - if( ! ( len > 6 && buf[0] == 0x30 && ( - ( buf[1] <= 0x7f && /* 1 length byte */ - buf[2] == 0x02 && buf[3] == 0x01 && buf[4] < 4 ) || - ( buf[1] == 0x81 && /* 2 length bytes */ - buf[3] == 0x02 && buf[4] == 0x01 && buf[5] < 4 ) || - ( buf[1] == 0x82 && /* 2 length bytes */ - buf[4] == 0x02 && buf[5] == 0x01 && buf[6] < 4 ) ) ) ) + if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) { polarssl_free( buf ); return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH );