diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index c5b5d6f9a..6ae3050a0 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -13,6 +13,8 @@ * for more details. */ +#include + #include "public_key.h" ENUM(key_type_names, KEY_RSA, KEY_DSA, @@ -21,7 +23,8 @@ ENUM(key_type_names, KEY_RSA, KEY_DSA, "DSA" ); -ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_ECDSA_521, +ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521, + "UNKNOWN", "DEFAULT", "RSA_EMSA_PKCS1_NULL", "RSA_EMSA_PKCS1_MD5", @@ -35,3 +38,33 @@ ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_ECDSA_521, "ECDSA-521", ); +/* + * Defined in header. + */ +signature_scheme_t signature_scheme_from_oid(int oid) +{ + switch (oid) + { + case OID_MD5_WITH_RSA: + case OID_MD5: + return SIGN_RSA_EMSA_PKCS1_MD5; + case OID_SHA1_WITH_RSA: + case OID_SHA1: + return SIGN_RSA_EMSA_PKCS1_SHA1; + case OID_SHA256_WITH_RSA: + case OID_SHA256: + return SIGN_RSA_EMSA_PKCS1_SHA256; + case OID_SHA384_WITH_RSA: + case OID_SHA384: + return SIGN_RSA_EMSA_PKCS1_SHA384; + case OID_SHA512_WITH_RSA: + case OID_SHA512: + return SIGN_RSA_EMSA_PKCS1_SHA512; + case OID_ECDSA_WITH_SHA1: + case OID_EC_PUBLICKEY: + return SIGN_ECDSA_WITH_SHA1; + default: + return SIGN_UNKNOWN; + } +} + diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h index d78791aeb..473a432b2 100644 --- a/src/libstrongswan/credentials/keys/public_key.h +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -58,6 +58,8 @@ extern enum_name_t *key_type_names; * variants is OCTET_STRING instead of the default BIT_STRING. */ enum signature_scheme_t { + /** Unknown signature scheme */ + SIGN_UNKNOWN, /** Default scheme of the underlying crypto system */ SIGN_DEFAULT, /** EMSA-PKCS1_v1.5 signature over digest without digestInfo */ @@ -164,4 +166,12 @@ struct public_key_t { void (*destroy)(public_key_t *this); }; +/** + * Conversion of ASN.1 signature or hash OID to signature scheme. + * + * @param oid ASN.1 OID + * @return signature_scheme, SIGN_UNKNOWN if OID is unsupported + */ +signature_scheme_t signature_scheme_from_oid(int oid); + #endif /** PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index 46055c633..638f96b44 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -779,31 +779,11 @@ static bool issued_by(private_x509_ac_t *this, certificate_t *issuer) return FALSE; } } - /* TODO: generic OID to scheme mapper? */ - switch (this->algorithm) - { - case OID_MD5_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_MD5; - break; - case OID_SHA1_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - break; - case OID_SHA256_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA256; - break; - case OID_SHA384_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA384; - break; - case OID_SHA512_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA512; - break; - case OID_ECDSA_WITH_SHA1: - scheme = SIGN_ECDSA_WITH_SHA1; - break; - default: - return FALSE; - } - if (key == NULL) + + /* determine signature scheme */ + scheme = signature_scheme_from_oid(this->algorithm); + + if (scheme == SIGN_UNKNOWN || key == NULL) { return FALSE; } diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index 34c121d7b..6fe1809c2 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -909,32 +909,14 @@ static bool issued_by(private_x509_cert_t *this, certificate_t *issuer) { return FALSE; } - /* TODO: generic OID to scheme mapper? */ - switch (this->algorithm) - { - case OID_MD5_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_MD5; - break; - case OID_SHA1_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - break; - case OID_SHA256_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA256; - break; - case OID_SHA384_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA384; - break; - case OID_SHA512_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA512; - break; - case OID_ECDSA_WITH_SHA1: - scheme = SIGN_ECDSA_WITH_SHA1; - break; - default: - return FALSE; - } + + /* get the public key of the issuer */ key = issuer->get_public_key(issuer); - if (key == NULL) + + /* determine signature scheme */ + scheme = signature_scheme_from_oid(this->algorithm); + + if (scheme == SIGN_UNKNOWN || key == NULL) { return FALSE; } diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c index 794d0fe8c..f502668cb 100644 --- a/src/libstrongswan/plugins/x509/x509_crl.c +++ b/src/libstrongswan/plugins/x509/x509_crl.c @@ -434,31 +434,11 @@ static bool issued_by(private_x509_crl_t *this, certificate_t *issuer) return FALSE; } } - /* TODO: generic OID to scheme mapper? */ - switch (this->algorithm) - { - case OID_MD5_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_MD5; - break; - case OID_SHA1_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - break; - case OID_SHA256_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA256; - break; - case OID_SHA384_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA384; - break; - case OID_SHA512_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA512; - break; - case OID_ECDSA_WITH_SHA1: - scheme = SIGN_ECDSA_WITH_SHA1; - break; - default: - return FALSE; - } - if (key == NULL) + + /* determine signature scheme */ + scheme = signature_scheme_from_oid(this->algorithm); + + if (scheme == SIGN_UNKNOWN || key == NULL) { return FALSE; } diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index 3f61dc6fe..1b3187258 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -724,32 +724,14 @@ static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer) { return FALSE; } - /* TODO: generic OID to scheme mapper? */ - switch (this->signatureAlgorithm) - { - case OID_MD5_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_MD5; - break; - case OID_SHA1_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - break; - case OID_SHA256_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA256; - break; - case OID_SHA384_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA384; - break; - case OID_SHA512_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA512; - break; - case OID_ECDSA_WITH_SHA1: - scheme = SIGN_ECDSA_WITH_SHA1; - break; - default: - return FALSE; - } + + /* get the public key of the issuer */ key = issuer->get_public_key(issuer); - if (key == NULL) + + /* determine signature scheme */ + scheme = signature_scheme_from_oid(this->signatureAlgorithm); + + if (scheme == SIGN_UNKNOWN || key == NULL) { return FALSE; } diff --git a/src/pluto/x509.c b/src/pluto/x509.c index ca926a9b8..535499618 100644 --- a/src/pluto/x509.c +++ b/src/pluto/x509.c @@ -1322,30 +1322,11 @@ bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm, const x509cert_t *issuer_cert) { public_key_t *key = issuer_cert->public_key; - signature_scheme_t scheme = SIGN_DEFAULT; + signature_scheme_t scheme = signature_scheme_from_oid(algorithm); - switch (algorithm) + if (scheme == SIGN_UNKNOWN) { - case OID_MD5_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_MD5; - break; - case OID_SHA1_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - break; - case OID_SHA256_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA256; - break; - case OID_SHA384_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA384; - break; - case OID_SHA512_WITH_RSA: - scheme = SIGN_RSA_EMSA_PKCS1_SHA512; - break; - case OID_ECDSA_WITH_SHA1: - scheme = SIGN_ECDSA_WITH_SHA1; - break; - default: - return FALSE; + return FALSE; } return key->verify(key, scheme, tbs, sig); } @@ -1353,33 +1334,13 @@ bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm, /** * Build an ASN.1 encoded PKCS#1 signature over a binary blob */ -chunk_t x509_build_signature(chunk_t tbs, int hash_alg, private_key_t *key, +chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key, bool bit_string) { - signature_scheme_t scheme = SIGN_DEFAULT; chunk_t signature; + signature_scheme_t scheme = signature_scheme_from_oid(algorithm); - switch (hash_alg) - { - case OID_MD5: - scheme = SIGN_RSA_EMSA_PKCS1_MD5; - break; - case OID_SHA1: - scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - break; - case OID_SHA256: - scheme = SIGN_RSA_EMSA_PKCS1_SHA256; - break; - case OID_SHA384: - scheme = SIGN_RSA_EMSA_PKCS1_SHA384; - break; - case OID_SHA512: - scheme = SIGN_RSA_EMSA_PKCS1_SHA512; - break; - default: - return chunk_empty; - } - if (!key->sign(key, scheme, tbs, &signature)) + if (scheme == SIGN_UNKNOWN || !key->sign(key, scheme, tbs, &signature)) { return chunk_empty; } diff --git a/src/pluto/x509.h b/src/pluto/x509.h index 1810cad06..ab0fbac9e 100644 --- a/src/pluto/x509.h +++ b/src/pluto/x509.h @@ -114,10 +114,12 @@ extern void parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber); extern chunk_t get_directoryName(chunk_t blob, int level, bool implicit); extern err_t check_validity(const x509cert_t *cert, time_t *until); + extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm, const x509cert_t *issuer_cert); -extern chunk_t x509_build_signature(chunk_t tbs, int hash_alg, private_key_t *key, - bool bit_string); +extern chunk_t x509_build_signature(chunk_t tbs, int algorithm, + private_key_t *key, bool bit_string); + extern bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until); extern x509cert_t* add_x509cert(x509cert_t *cert); extern x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid,