When parsing a PKCS#1 RSAPrivateKey structure, all parameters are always
present. After importing them, we need to call rsa_complete() for the sake of
alternative implementations. That function interprets zero as a signal for
"this parameter was not provided". As that's never the case, we mustn't pass
any zero value to that function, so we need to explicitly check for it.
Context: This commit makes a change to mbedtls_pk_parse_key() which
is responsible for parsing of private keys. The function doesn't know
the key format in advance (PEM vs. DER, encrypted vs. unencrypted) and
tries them one by one, resetting the PK context in between.
Issue: The previous code resets the PK context through a call to
mbedtls_pk_free() along, lacking the accompanying mbedtls_pk_init()
call. Practically, this is not an issue because functionally
mbedtls_pk_free() + mbedtls_pk_init() is equivalent to mbedtls_pk_free()
with the current implementation of these functions, but strictly
speaking it's nonetheless a violation of the API semantics according
to which xxx_free() functions leave a context in uninitialized state.
(yet not entirely random, because xxx_free() functions must be idempotent,
so they cannot just fill the context they operate on with garbage).
Change: The commit adds calls to mbedtls_pk_init() after those calls
to mbedtls_pk_free() within mbedtls_pk_parse_key() after which the
PK context might still be used.
The relevant ASN.1 definitions for a PKCS#8 encoded Elliptic Curve key are:
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
ECParameters ::= CHOICE {
namedCurve OBJECT IDENTIFIER
-- implicitCurve NULL
-- specifiedCurve SpecifiedECDomain
}
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
publicKey [1] BIT STRING OPTIONAL
}
Because of the two optional fields, there are 4 possible variants that need to
be parsed: no optional fields, only parameters, only public key, and both
optional fields. Previously mbedTLS was unable to parse keys with "only
parameters". Also, only "only public key" was tested. There was a test for "no
optional fields", but it was labelled incorrectly as SEC.1 and not run because
of a great renaming mixup.
The function `pk_get_rsapubkey` originally performed some basic
sanity checks (e.g. on the size of public exponent) on the parsed
RSA public key by a call to `mbedtls_rsa_check_pubkey`.
This check was dropped because it is not possible to thoroughly
check full parameter sanity (i.e. that (-)^E is a bijection on Z/NZ).
Still, for the sake of not silently changing existing behavior,
this commit puts back the call to `mbedtls_rsa_check_pubkey`.
Fix missing definition of mbedtls_zeroize when MBEDTLS_FS_IO is
disabled in the configuration.
Introduced by e7707228b4
Merge remote-tracking branch 'upstream-public/pr/1062' into development
As the optional RSA parameters DP, DQ and QP are effectively discarded (they are only considered for their length to
ensure that the key fills the entire buffer), it is not necessary to read them into separate MPI's.
State explicitly that `pk_parse_pkcs8_undencrypted_der` and `pk_parse_key_pkcs8_encrypted_der` are not responsible for
zeroizing and freeing the provided key buffer.
The stack buffer used to hold the decrypted key in pk_parse_pkcs8_encrypted_der
was statically sized to 2048 bytes, which is not enough for DER encoded 4096bit
RSA keys.
This commit resolves the problem by performing the key-decryption in-place,
circumventing the introduction of another stack or heap copy of the key.
There are two situations where pk_parse_pkcs8_encrypted_der is invoked:
1. When processing a PEM-encoded encrypted key in mbedtls_pk_parse_key.
This does not need adaption since the PEM context used to hold the decoded
key is already constructed and owned by mbedtls_pk_parse_key.
2. When processing a DER-encoded encrypted key in mbedtls_pk_parse_key.
In this case, mbedtls_pk_parse_key calls pk_parse_pkcs8_encrypted_der with
the buffer provided by the user, which is declared const. The commit
therefore adds a small code paths making a copy of the keybuffer before
calling pk_parse_pkcs8_encrypted_der.
Fixes many typos, and errors in comments.
* Clarifies many comments
* Grammar correction in config.pl help text
* Removed comment about MBEDTLS_X509_EXT_NS_CERT_TYPE.
* Comment typo fix (Dont => Don't)
* Comment typo fix (assure => ensure)
* Comment typo fix (byes => bytes)
* Added citation for quoted standard
* Comment typo fix (one complement => 1's complement)
The is some debate about whether to prefer "one's complement", "ones'
complement", or "1's complement". The more recent RFCs related to TLS
(RFC 6347, RFC 4347, etc) use " 1's complement", so I followed that
convention.
* Added missing ")" in comment
* Comment alignment
* Incorrect comment after #endif