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*,
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*,