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.
This commit is contained in:
parent
607f10dca4
commit
bd267c863f
|
@ -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*,
|
||||
|
|
|
@ -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*,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue