From: Tobias Brunner Date: Fri, 10 Aug 2018 07:02:26 +0000 (+0200) Subject: botan: Encode private keys as PKCS#8 X-Git-Tag: 5.7.0rc1~4^2~15 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=bd267c863f3a23f79694d309568e72569ff8a5be;p=thirdparty%2Fstrongswan.git botan: Encode private keys as PKCS#8 Since we can now parse that encoding directly we can simplify the private key export and stick to PKCS#8. --- diff --git a/src/libstrongswan/plugins/botan/botan_ec_private_key.c b/src/libstrongswan/plugins/botan/botan_ec_private_key.c index 78ba43f811..f8dbb66d78 100644 --- a/src/libstrongswan/plugins/botan/botan_ec_private_key.c +++ b/src/libstrongswan/plugins/botan/botan_ec_private_key.c @@ -209,123 +209,11 @@ METHOD(private_key_t, get_fingerprint, bool, return success; } -/** - * Get a field from the private key as chunk - */ -static bool get_field_chunk(botan_privkey_t key, char *field, chunk_t *out) -{ - botan_mp_t val; - - *out = chunk_empty; - - if (botan_mp_init(&val)) - { - return FALSE; - } - - if (botan_privkey_get_field(val, key, field) || - botan_mp_num_bytes(val, &out->len)) - { - botan_mp_destroy(val); - return FALSE; - } - - *out = chunk_alloc(out->len); - - if (botan_mp_to_bin(val, out->ptr)) - { - botan_mp_destroy(val); - chunk_free(out); - return FALSE; - } - botan_mp_destroy(val); - return TRUE; -} - -/** - * Encodes the public key as ASN.1 BIT STRING (0x04 || x || y) - */ -static bool get_pubkey_bitstring(botan_privkey_t key, chunk_t *out) -{ - chunk_t p, x, y, pub; - size_t len; - - if (!get_field_chunk(key, "p", &p)) - { - return FALSE; - } - len = p.len; - chunk_free(&p); - - if (!get_field_chunk(key, "public_x", &x)) - { - return FALSE; - } - if (!get_field_chunk(key, "public_y", &y)) - { - chunk_free(&x); - return FALSE; - } - - pub = chunk_alloca(2 * len); - memset(pub.ptr, 0, pub.len); - memcpy(pub.ptr + (len - x.len), x.ptr, x.len); - memcpy(pub.ptr + len + (len - y.len), y.ptr, y.len); - chunk_free(&x); - chunk_free(&y); - - *out = asn1_wrap(ASN1_BIT_STRING, "ccc", - /* unused bits in the bit string */ - chunk_from_chars(0x00), - /* uncompressed format */ - chunk_from_chars(0x04), pub); - return TRUE; -} - METHOD(private_key_t, get_encoding, bool, private_botan_ec_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding) { - switch (type) - { - case PRIVKEY_ASN1_DER: - case PRIVKEY_PEM: - { - chunk_t priv, pub; - bool success = TRUE; - - if (!get_field_chunk(this->key, "x", &priv)) - { - return FALSE; - } - if (!get_pubkey_bitstring(this->key, &pub)) - { - chunk_clear(&priv); - return FALSE; - } - - *encoding = asn1_wrap(ASN1_SEQUENCE, "msmm", - asn1_integer("c", chunk_from_chars(0x01)), - asn1_wrap(ASN1_OCTET_STRING, "s", priv), - asn1_wrap(ASN1_CONTEXT_C_0, "m", - asn1_build_known_oid(this->oid)), - asn1_wrap(ASN1_CONTEXT_C_1, "m", pub)); - - if (type == PRIVKEY_PEM) - { - chunk_t asn1_encoding = *encoding; - - success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM, - NULL, encoding, - CRED_PART_ECDSA_PRIV_ASN1_DER, - asn1_encoding, CRED_PART_END); - chunk_clear(&asn1_encoding); - } - return success; - } - default: - return FALSE; - } + return botan_get_privkey_encoding(this->key, type, encoding); } METHOD(private_key_t, get_ref, private_key_t*, diff --git a/src/libstrongswan/plugins/botan/botan_rsa_private_key.c b/src/libstrongswan/plugins/botan/botan_rsa_private_key.c index 8b2583b96c..558bb70f75 100644 --- a/src/libstrongswan/plugins/botan/botan_rsa_private_key.c +++ b/src/libstrongswan/plugins/botan/botan_rsa_private_key.c @@ -257,38 +257,7 @@ METHOD(private_key_t, get_encoding, bool, private_botan_rsa_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding) { - switch (type) - { - case PRIVKEY_ASN1_DER: - case PRIVKEY_PEM: - { - uint32_t format = BOTAN_PRIVKEY_EXPORT_FLAG_DER; - size_t len = 0; - bool success = TRUE; - - if (type == PRIVKEY_PEM) - { - format = BOTAN_PRIVKEY_EXPORT_FLAG_PEM; - } - - if (botan_privkey_rsa_get_privkey(this->key, NULL, &len, format) - != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE) - { - return FALSE; - } - - *encoding = chunk_alloc(len); - if (botan_privkey_rsa_get_privkey(this->key, encoding->ptr, &len, - format)) - { - chunk_clear(encoding); - return FALSE; - } - return success; - } - default: - return FALSE; - } + return botan_get_privkey_encoding(this->key, type, encoding); } METHOD(private_key_t, get_ref, private_key_t*, diff --git a/src/libstrongswan/plugins/botan/botan_util.c b/src/libstrongswan/plugins/botan/botan_util.c index 9dcf592c54..860d376c3b 100644 --- a/src/libstrongswan/plugins/botan/botan_util.c +++ b/src/libstrongswan/plugins/botan/botan_util.c @@ -108,6 +108,39 @@ bool botan_get_encoding(botan_pubkey_t pubkey, cred_encoding_type_t type, return success; } +/* + * Described in header + */ +bool botan_get_privkey_encoding(botan_privkey_t key, cred_encoding_type_t type, + chunk_t *encoding) +{ + uint32_t format = BOTAN_PRIVKEY_EXPORT_FLAG_DER; + + switch (type) + { + case PRIVKEY_PEM: + format = BOTAN_PRIVKEY_EXPORT_FLAG_PEM; + /* fall-through */ + case PRIVKEY_ASN1_DER: + encoding->len = 0; + if (botan_privkey_export(key, NULL, &encoding->len, format) + != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE) + { + return FALSE; + } + *encoding = chunk_alloc(encoding->len); + if (botan_privkey_export(key, encoding->ptr, &encoding->len, + format)) + { + chunk_free(encoding); + return FALSE; + } + return TRUE; + default: + return FALSE; + } +} + /* * Described in header */ diff --git a/src/libstrongswan/plugins/botan/botan_util.h b/src/libstrongswan/plugins/botan/botan_util.h index 1f4b96f6e6..2c6b1f816f 100644 --- a/src/libstrongswan/plugins/botan/botan_util.h +++ b/src/libstrongswan/plugins/botan/botan_util.h @@ -64,6 +64,17 @@ const char *botan_get_hash(hash_algorithm_t hash); bool botan_get_encoding(botan_pubkey_t pubkey, cred_encoding_type_t type, chunk_t *encoding); +/** + * Get the encoding of a botan_privkey_t. + * + * @param key private key object + * @param type encoding type + * @param encoding allocated encoding + * @return TRUE if encoding successful + */ +bool botan_get_privkey_encoding(botan_privkey_t key, cred_encoding_type_t type, + chunk_t *encoding); + /** * Get the fingerprint of a botan_pubkey_t. *