1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-08-05 19:35:48 +03:00

Merge pull request #8010 from marekjansta/fix-x509-ec-algorithm-identifier-2.28

Backport 2.28: Fixed x509 certificate generation to conform to RFCs when using ECC key
This commit is contained in:
Gilles Peskine
2023-08-07 19:14:52 +00:00
committed by GitHub
12 changed files with 101 additions and 17 deletions

View File

@@ -0,0 +1,4 @@
Bugfix
* Fix x509 certificate generation to conform to RFC 5480 / RFC 5758 when
using ECC key. The certificate was rejected by some crypto frameworks.
Fixes #2924.

View File

@@ -158,6 +158,27 @@ int mbedtls_asn1_write_algorithm_identifier(unsigned char **p,
const char *oid, size_t oid_len,
size_t par_len);
/**
* \brief Write an AlgorithmIdentifier sequence in ASN.1 format.
*
* \note This function works backwards in data buffer.
*
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param oid The OID of the algorithm to write.
* \param oid_len The length of the algorithm's OID.
* \param par_len The length of the parameters, which must be already written.
* \param has_par If there are any parameters. If 0, par_len must be 0. If 1
* and \p par_len is 0, NULL parameters are added.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/
int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p,
unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len, int has_par);
/**
* \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
* in ASN.1 format.

View File

@@ -361,7 +361,8 @@ int mbedtls_x509_write_names(unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first);
int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
unsigned char *sig, size_t size);
unsigned char *sig, size_t size,
mbedtls_pk_type_t pk_alg);
#define MBEDTLS_X509_SAFE_SNPRINTF \
do { \

View File

@@ -194,14 +194,23 @@ int mbedtls_asn1_write_oid(unsigned char **p, unsigned char *start,
int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len)
{
return mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, par_len, 1);
}
int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len, int has_par)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if (par_len == 0) {
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start));
} else {
len += par_len;
if (has_par) {
if (par_len == 0) {
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start));
} else {
len += par_len;
}
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len));

View File

@@ -285,9 +285,11 @@ int mbedtls_x509_write_names(unsigned char **p, unsigned char *start,
int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
unsigned char *sig, size_t size)
unsigned char *sig, size_t size,
mbedtls_pk_type_t pk_alg)
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int write_null_par;
size_t len = 0;
if (*p < start || (size_t) (*p - start) < size) {
@@ -310,8 +312,19 @@ int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start,
// Write OID
//
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_algorithm_identifier(p, start, oid,
oid_len, 0));
if (pk_alg == MBEDTLS_PK_ECDSA) {
/*
* The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature
* algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and
* https://www.rfc-editor.org/rfc/rfc5758#section-3.
*/
write_null_par = 0;
} else {
write_null_par = 1;
}
MBEDTLS_ASN1_CHK_ADD(len,
mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len,
0, write_null_par));
return (int) len;
}

View File

@@ -342,6 +342,7 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx,
size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
int write_sig_null_par;
/*
* Prepare data to be signed at the end of the target buffer
@@ -433,9 +434,20 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx,
/*
* Signature ::= AlgorithmIdentifier
*/
if (pk_alg == MBEDTLS_PK_ECDSA) {
/*
* The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature
* algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and
* https://www.rfc-editor.org/rfc/rfc5758#section-3.
*/
write_sig_null_par = 0;
} else {
write_sig_null_par = 1;
}
MBEDTLS_ASN1_CHK_ADD(len,
mbedtls_asn1_write_algorithm_identifier(&c, buf,
sig_oid, strlen(sig_oid), 0));
mbedtls_asn1_write_algorithm_identifier_ext(&c, buf,
sig_oid, strlen(sig_oid),
0, write_sig_null_par));
/*
* Serial ::= INTEGER
@@ -492,8 +504,8 @@ int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx,
* into the CRT buffer. */
c2 = buf + size;
MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len, mbedtls_x509_write_sig(&c2, c,
sig_oid, sig_oid_len, sig,
sig_len));
sig_oid, sig_oid_len,
sig, sig_len, pk_alg));
/*
* Memory layout after this step:

View File

@@ -265,7 +265,7 @@ static int x509write_csr_der_internal(mbedtls_x509write_csr *ctx,
c2 = buf + size;
MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len,
mbedtls_x509_write_sig(&c2, buf + len, sig_oid, sig_oid_len,
sig, sig_len));
sig, sig_len, pk_alg));
/*
* Compact the space between the CSR data and signature by moving the

View File

@@ -1210,7 +1210,7 @@ all_final += server5-badsign.crt
# The use of 'Server 1' in the DN is intentional here, as the DN is hardcoded in the x509_write test suite.'
server5.req.ku.sha1: server5.key
$(MBEDTLS_CERT_REQ) output_file=$@ filename=$< key_usage=digital_signature,non_repudiation subject_name="C=NL,O=PolarSSL,CN=PolarSSL Server 1" md=SHA1
$(OPENSSL) req -key $< -out $@ -new -nodes -subj "/C=NL/O=PolarSSL/CN=PolarSSL Server 1" -sha1 -addext keyUsage=digitalSignature,nonRepudiation
all_final += server5.req.ku.sha1
# server6*

View File

@@ -76,6 +76,10 @@ List of certificates:
-badsign.crt: S5 with corrupted signature
-expired.crt: S5 with "not after" date in the past
-future.crt: S5 with "not before" date in the future
-non-compliant.crt: S5, RFC non-compliant
(with forbidden EC algorithm identifier NULL parameter)
generated by (before fix):
cert_write subject_key=server5.key subject_name="CN=Test EC RFC non-compliant" issuer_crt=test-ca2.crt issuer_key=test-ca2.key
-selfsigned.crt: Self-signed cert with S5 key
-ss-expired.crt: Self-signed cert with S5 key, expired
-ss-forgeca.crt: Copy of test-int-ca3 self-signed with S5 key

View File

@@ -0,0 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIBwjCCAUagAwIBAgIBATAMBggqhkjOPQQDAgUAMD4xCzAJBgNVBAYTAk5MMREw
DwYDVQQKDAhQb2xhclNTTDEcMBoGA1UEAwwTUG9sYXJzc2wgVGVzdCBFQyBDQTAe
Fw0wMTAxMDEwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMCQxIjAgBgNVBAMMGVRlc3Qg
RUMgUkZDIG5vbi1jb21wbGlhbnQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ3
zFbZdgkeWnI+x1kt/yBu7nz5BpF00K0UtfdoIllikk7lANgjEf/qL9I0XV0WvYqI
wmt3DVXNiioO+gHItO3/o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRQYaWP1AfZ
14IBDOVlf4xjRqcTvjAfBgNVHSMEGDAWgBSdbSAkSQE/K8t4tRm8fiTJ2/s2fDAM
BggqhkjOPQQDAgUAA2gAMGUCMAJ3J/DooFSaBG2OhzyWai32q6INDZfoS2bToSKf
gy6hbJiIX/G9eFts5+BJQ3QpjgIxALRmIgdR91BDdqpeF5JCmhgjbfbgMQ7mrMeS
ZGfNyFyjS75QnIA6nKryQmgPXo+sCQ==
-----END CERTIFICATE-----

View File

@@ -1,8 +1,8 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBFjCBvAIBADA8MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGjAY
MIIBFDCBvAIBADA8MQswCQYDVQQGEwJOTDERMA8GA1UECgwIUG9sYXJTU0wxGjAY
BgNVBAMMEVBvbGFyU1NMIFNlcnZlciAxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
QgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/6i/SNF1d
Fr2KiMJrdw1VzYoqDvoByLTt/6AeMBwGCSqGSIb3DQEJDjEPMA0wCwYDVR0PBAQD
AgbAMAsGByqGSM49BAEFAANIADBFAiEAnIKF+xKk0iEuN4MHd4FZWNvrznLQgkeg
2n8ejjreTzcCIAH34z2TycuMpWQRhpV+YT988pBWR67LAg7REyZnjSAB
AgbAMAkGByqGSM49BAEDSAAwRQIhAJyChfsSpNIhLjeDB3eBWVjb685y0IJHoNp/
Ho463k83AiAB9+M9k8nLjKVkEYaVfmE/fPKQVkeuywIO0RMmZ40gAQ==
-----END CERTIFICATE REQUEST-----

View File

@@ -2890,6 +2890,14 @@ X509 File parse (Algorithm Params Tag mismatch)
depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C
mbedtls_x509_crt_parse_file:"data_files/parse_input/cli-rsa-sha256-badalg.crt.der":MBEDTLS_ERR_X509_SIG_MISMATCH:0
X509 File parse (does not conform to RFC 5480 / RFC 5758 - AlgorithmIdentifier's parameters field is present, mbedTLS generated before bugfix, OK)
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
x509parse_crt_file:"data_files/parse_input/server5-non-compliant.crt":0
X509 File parse (conforms to RFC 5480 / RFC 5758 - AlgorithmIdentifier's parameters field must be absent for ECDSA)
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C
x509parse_crt_file:"data_files/parse_input/server5.crt":0
X509 Get time (UTC no issues)
depends_on:MBEDTLS_X509_USE_C
x509_get_time:MBEDTLS_ASN1_UTC_TIME:"500101000000Z":0:1950:1:1:0:0:0