diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2014-11-04 20:51:33 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2014-11-29 14:51:16 +0100 |
commit | 56009f2001a4678872c360d143fc3095803cb824 (patch) | |
tree | 1e217db0d9dc3447bf56bc34619611ea03190cb8 | |
parent | 37bfe44358033639d6e87bf122def5a781cbf876 (diff) | |
download | strongswan-56009f2001a4678872c360d143fc3095803cb824.tar.bz2 strongswan-56009f2001a4678872c360d143fc3095803cb824.tar.xz |
Store and parse BLISS private and public keys in DER and PEM format
Additionally generate SHA-1 fingerprints of raw BLISS subjectPublicKey
and subjectPublicKeyInfo objects.
Some basic functions used by the bliss_public_key class are shared
with the bliss_private_key class.
-rw-r--r-- | src/libstrongswan/asn1/oid.txt | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/cred_encoding.h | 4 | ||||
-rw-r--r-- | src/libstrongswan/plugins/bliss/bliss_private_key.c | 200 | ||||
-rw-r--r-- | src/libstrongswan/plugins/bliss/bliss_public_key.c | 221 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_encoder.c | 11 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pem/pem_plugin.c | 5 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs1/pkcs1_builder.c | 9 | ||||
-rw-r--r-- | src/pki/commands/print.c | 14 | ||||
-rw-r--r-- | src/pki/commands/pub.c | 7 |
9 files changed, 441 insertions, 32 deletions
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt index 5d74f4082..e0e0e18c1 100644 --- a/src/libstrongswan/asn1/oid.txt +++ b/src/libstrongswan/asn1/oid.txt @@ -212,7 +212,7 @@ 0x03 "e-voting" 0x05 "BLISS" 0x01 "keyType" - 0x01 "blissPublicKey" OID_BLISS + 0x01 "blissPublicKey" OID_BLISS_PUBLICKEY 0x02 "parameters" 0x01 "BLISS-I" OID_BLISS_I 0x02 "BLISS-II" OID_BLISS_II diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h index a6c9c30af..b4d1f4c3c 100644 --- a/src/libstrongswan/credentials/cred_encoding.h +++ b/src/libstrongswan/credentials/cred_encoding.h @@ -144,6 +144,10 @@ enum cred_encoding_part_t { CRED_PART_PKCS10_ASN1_DER, /** a PGP encoded certificate */ CRED_PART_PGP_CERT, + /** a DER encoded BLISS public key */ + CRED_PART_BLISS_PUB_ASN1_DER, + /** a DER encoded BLISS private key */ + CRED_PART_BLISS_PRIV_ASN1_DER, CRED_PART_END, }; diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.c b/src/libstrongswan/plugins/bliss/bliss_private_key.c index 2af6f2b8a..df7bbbf52 100644 --- a/src/libstrongswan/plugins/bliss/bliss_private_key.c +++ b/src/libstrongswan/plugins/bliss/bliss_private_key.c @@ -18,6 +18,9 @@ #include "bliss_fft.h" #include <crypto/mgf1/mgf1_bitspender.h> +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <asn1/oid.h> #define _GNU_SOURCE #include <stdlib.h> @@ -27,6 +30,18 @@ typedef struct private_bliss_private_key_t private_bliss_private_key_t; #define SECRET_KEY_TRIALS_MAX 30 /** + * Functions shared with bliss_public_key class + */ +extern uint32_t* bliss_public_key_from_asn1(chunk_t object, int n); + +extern chunk_t bliss_public_key_encode(uint32_t *pubkey, int n); + +extern chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n); + +extern bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n, + cred_encoding_type_t type, chunk_t *fp); + +/** * Private data of a bliss_private_key_t object. */ struct private_bliss_private_key_t { @@ -41,6 +56,21 @@ struct private_bliss_private_key_t { bliss_param_set_t *set; /** + * BLISS secret key S1 (coefficients of polynomial f) + */ + int8_t *s1; + + /** + * BLISS secret key S2 (coefficients of polynomial 2g + 1) + */ + int8_t *s2; + + /** + * BLISS public key a (coefficients of polynomial (2g + 1)/f) + */ + uint32_t *a; + + /** * reference count */ refcount_t ref; @@ -87,7 +117,14 @@ METHOD(private_key_t, get_keysize, int, METHOD(private_key_t, get_public_key, public_key_t*, private_bliss_private_key_t *this) { - public_key_t *public = NULL; + public_key_t *public; + chunk_t pubkey; + + pubkey = bliss_public_key_info_encode(this->set->oid, this->a, + this->set->n); + public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS, + BUILD_BLOB_ASN1_DER, pubkey, BUILD_END); + free(pubkey.ptr); return public; } @@ -96,17 +133,55 @@ METHOD(private_key_t, get_encoding, bool, private_bliss_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding) { - bool success = TRUE; + switch (type) + { + case PRIVKEY_ASN1_DER: + case PRIVKEY_PEM: + { + chunk_t s1_chunk, s2_chunk, pubkey; + bool success = TRUE; - *encoding = chunk_empty; + pubkey = bliss_public_key_encode(this->a, this->set->n); - return success; + /* Build private key as two polynomials with 8 bit coefficients */ + s1_chunk = chunk_create(this->s1, this->set->n); + s2_chunk = chunk_create(this->s2, this->set->n); + + *encoding = asn1_wrap(ASN1_SEQUENCE, "mmss", + asn1_build_known_oid(this->set->oid), + pubkey, + asn1_simple_object(ASN1_OCTET_STRING, s1_chunk), + asn1_simple_object(ASN1_OCTET_STRING, s2_chunk) + ); + + if (type == PRIVKEY_PEM) + { + chunk_t asn1_encoding = *encoding; + + success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM, + NULL, encoding, CRED_PART_BLISS_PRIV_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } + return success; + } + default: + return FALSE; + } } METHOD(private_key_t, get_fingerprint, bool, private_bliss_private_key_t *this, cred_encoding_type_t type, chunk_t *fp) { - bool success = FALSE; + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + success = bliss_public_key_fingerprint(this->set->oid, this->a, + this->set->n, type, fp); + lib->encoding->cache(lib->encoding, type, this, *fp); return success; } @@ -123,6 +198,10 @@ METHOD(private_key_t, destroy, void, { if (ref_put(&this->ref)) { + lib->encoding->clear_cache(lib->encoding, this); + free(this->s1); + free(this->s2); + free(this->a); free(this); } } @@ -438,9 +517,8 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) private_bliss_private_key_t *this; u_int key_size = 1; int i, n, trials = 0; - int8_t *s1 = NULL, *s2 = NULL; + uint32_t *A, *S1, *S2; uint16_t q; - uint32_t *a, *A, *S1, *S2; bool success = FALSE; bliss_param_set_t *set; bliss_fft_t *fft; @@ -487,8 +565,8 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) /* Some vectors needed to derive the publi key */ S1 = malloc(n * sizeof(uint32_t)); S2 = malloc(n * sizeof(uint32_t)); - A = malloc(n * sizeof(uint32_t)); - a = malloc(n * sizeof(uint32_t)); + A = malloc(n * sizeof(uint32_t)); + this->a = malloc(n * sizeof(uint32_t)); /* Instantiate a true random generator */ rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE); @@ -496,7 +574,7 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) /* Loop until we have an invertible polynomial s1 */ do { - if (!create_secret(this, rng, &s1, &s2, &trials)) + if (!create_secret(this, rng, &this->s1, &this->s2, &trials)) { break; } @@ -504,8 +582,8 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) /* Convert signed arrays to unsigned arrays before FFT */ for (i = 0; i < n; i++) { - S1[i] = (s1[i] < 0) ? s1[i] + q : s1[i]; - S1[i] = (s2[i] < 0) ? s2[i] + q : s2[i]; + S1[i] = (this->s1[i] < 0) ? this->s1[i] + q : this->s1[i]; + S2[i] = (this->s2[i] > 0) ? q - this->s2[i] : -this->s2[i]; } fft->transform(fft, S1, S1, FALSE); fft->transform(fft, S2, S2, FALSE); @@ -516,10 +594,10 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) if (S1[i] == 0) { DBG1(DBG_LIB, "S1[%d] is zero - s1 is not invertible", i); - free(s1); - s1 = NULL; - free(s2); - s2 = NULL; + free(this->s1); + free(this->s2); + this->s1 = NULL; + this->s2 = NULL; success = FALSE; break; } @@ -534,13 +612,13 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) if (success) { - fft->transform(fft, A, a, TRUE); + fft->transform(fft, A, this->a, TRUE); DBG4(DBG_LIB, " i f g a F G A"); for (i = 0; i < n; i++) { DBG4(DBG_LIB, "%4d %3d %3d %5u %5u %5u %5u", - i, s1[i], s2[i], a[i], S1[i], S2[i], A[i]); + i, this->s1[i], this->s2[i], this->a[i], S1[i], S2[i], A[i]); } } else @@ -551,9 +629,6 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) /* Cleanup */ fft->destroy(fft); rng->destroy(rng); - free(s1); - free(s2); - free(a); free(A); free(S1); free(S2); @@ -562,24 +637,107 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) } /** + * ASN.1 definition of a BLISS private key + */ +static const asn1Object_t privkeyObjects[] = { + { 0, "BLISSPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "keyType", ASN1_OID, ASN1_BODY }, /* 1 */ + { 1, "public", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ + { 1, "secret1", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */ + { 1, "secret2", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PRIV_KEY_TYPE 1 +#define PRIV_KEY_PUBLIC 2 +#define PRIV_KEY_SECRET1 3 +#define PRIV_KEY_SECRET2 4 + +/** * See header. */ bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args) { private_bliss_private_key_t *this; + chunk_t key = chunk_empty, object; + asn1_parser_t *parser; + bool success = FALSE; + int objectID, oid; while (TRUE) { switch (va_arg(args, builder_part_t)) { + case BUILD_BLOB_ASN1_DER: + key = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; default: return NULL; } break; } + if (key.len == 0) + { + return NULL; + } this = bliss_private_key_create_empty(); + parser = asn1_parser_create(privkeyObjects, key); + parser->set_flags(parser, FALSE, TRUE); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PRIV_KEY_TYPE: + oid = asn1_known_oid(object); + if (oid == OID_UNKNOWN) + { + goto end; + } + this->set = bliss_param_set_get_by_oid(oid); + if (this->set == NULL) + { + goto end; + } + break; + case PRIV_KEY_PUBLIC: + if (object.len != 2*this->set->n) + { + goto end; + } + this->a = bliss_public_key_from_asn1(object, this->set->n); + break; + case PRIV_KEY_SECRET1: + if (object.len != this->set->n) + { + goto end; + } + this->s1 = malloc(this->set->n); + memcpy(this->s1, object.ptr, object.len); + break; + case PRIV_KEY_SECRET2: + if (object.len != this->set->n) + { + goto end; + } + this->s2 = malloc(this->set->n); + memcpy(this->s2, object.ptr, object.len); + break; + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + if (!success) + { + destroy(this); + return NULL; + } + return &this->public; } diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.c b/src/libstrongswan/plugins/bliss/bliss_public_key.c index 002bf349a..9d39ae64f 100644 --- a/src/libstrongswan/plugins/bliss/bliss_public_key.c +++ b/src/libstrongswan/plugins/bliss/bliss_public_key.c @@ -14,6 +14,11 @@ */ #include "bliss_public_key.h" +#include "bliss_param_set.h" + +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <asn1/oid.h> typedef struct private_bliss_public_key_t private_bliss_public_key_t; @@ -27,9 +32,14 @@ struct private_bliss_public_key_t { bliss_public_key_t public; /** - * BLISS type + * BLISS signature parameter set */ - u_int key_size; + bliss_param_set_t *set; + + /** + * BLISS public key a (coefficients of polynomial (2g + 1)/f) + */ + uint32_t *a; /** * reference counter @@ -72,7 +82,104 @@ METHOD(public_key_t, encrypt_, bool, METHOD(public_key_t, get_keysize, int, private_bliss_public_key_t *this) { - return this->key_size; + return this->set->strength; +} + +/** + * Parse an ASN.1 OCTET STRING into an array of public key coefficients + */ +uint32_t* bliss_public_key_from_asn1(chunk_t object, int n) +{ + uint32_t *pubkey; + uint16_t coeff; + u_char *pos; + int i; + + pubkey = malloc(n * sizeof(uint32_t)); + pos = object.ptr; + + for (i = 0; i < n; i++) + { + coeff = untoh16(pos); + pubkey[i] = (uint32_t)coeff; + pos += 2; + } + + return pubkey; +} + +/** + * Encode a raw BLISS subjectPublicKey in ASN.1 DER format + */ +chunk_t bliss_public_key_encode(uint32_t *pubkey, int n) +{ + u_char *pos; + chunk_t encoding; + int i; + + pos = asn1_build_object(&encoding, ASN1_OCTET_STRING, 2 * n); + + for (i = 0; i < n; i++) + { + htoun16(pos, (uint16_t)pubkey[i]); + pos += 2; + } + + return encoding; +} + +/** + * Encode a BLISS subjectPublicKeyInfo record in ASN.1 DER format + */ +chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n) +{ + chunk_t encoding, pubkey_encoding; + + pubkey_encoding = bliss_public_key_encode(pubkey, n); + + encoding = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_build_known_oid(OID_BLISS_PUBLICKEY), + asn1_build_known_oid(oid)), + asn1_bitstring("m", pubkey_encoding)); + + return encoding; +} + +/** + * Generate a BLISS public key fingerprint + */ +bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n, + cred_encoding_type_t type, chunk_t *fp) +{ + hasher_t *hasher; + chunk_t key; + + switch (type) + { + case KEYID_PUBKEY_SHA1: + key = bliss_public_key_encode(pubkey, n); + break; + case KEYID_PUBKEY_INFO_SHA1: + key = bliss_public_key_info_encode(oid, pubkey, n); + break; + default: + return FALSE; + } + + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher || !hasher->allocate_hash(hasher, key, fp)) + { + DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed"); + DESTROY_IF(hasher); + free(key.ptr); + + return FALSE; + } + hasher->destroy(hasher); + free(key.ptr); + + return TRUE; } METHOD(public_key_t, get_encoding, bool, @@ -81,15 +188,33 @@ METHOD(public_key_t, get_encoding, bool, { bool success = TRUE; - *encoding = chunk_empty; + *encoding = bliss_public_key_info_encode(this->set->oid, this->a, + this->set->n); + + if (type != PUBKEY_SPKI_ASN1_DER) + { + chunk_t asn1_encoding = *encoding; + success = lib->encoding->encode(lib->encoding, type, + NULL, encoding, CRED_PART_BLISS_PUB_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } return success; } METHOD(public_key_t, get_fingerprint, bool, private_bliss_public_key_t *this, cred_encoding_type_t type, chunk_t *fp) { - bool success = FALSE; + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + success = bliss_public_key_fingerprint(this->set->oid, this->a, + this->set->n, type, fp); + lib->encoding->cache(lib->encoding, type, this, *fp); return success; } @@ -106,21 +231,42 @@ METHOD(public_key_t, destroy, void, { if (ref_put(&this->ref)) { + lib->encoding->clear_cache(lib->encoding, this); + free(this->a); free(this); } } /** + * ASN.1 definition of a BLISS public key + */ +static const asn1Object_t pubkeyObjects[] = { + { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */ + { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */ + { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM 1 +#define BLISS_SUBJECT_PUBLIC_KEY 2 + +/** * See header. */ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args) { private_bliss_public_key_t *this; + chunk_t blob = chunk_empty, object, param; + asn1_parser_t *parser; + bool success = FALSE; + int objectID, oid; while (TRUE) { switch (va_arg(args, builder_part_t)) { + case BUILD_BLOB_ASN1_DER: + blob = va_arg(args, chunk_t); + continue; case BUILD_END: break; default: @@ -129,6 +275,11 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args) break; } + if (blob.len == 0) + { + return NULL; + } + INIT(this, .public = { .key = { @@ -147,5 +298,65 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args) .ref = 1, ); + parser = asn1_parser_create(pubkeyObjects, blob); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM: + { + oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser)+1, ¶m); + if (oid != OID_BLISS_PUBLICKEY) + { + goto end; + } + if (!asn1_parse_simple_object(¶m, ASN1_OID, + parser->get_level(parser)+3, "blissKeyType")) + { + goto end; + } + oid = asn1_known_oid(param); + if (oid == OID_UNKNOWN) + { + goto end; + } + this->set = bliss_param_set_get_by_oid(oid); + if (this->set == NULL) + { + goto end; + } + break; + } + case BLISS_SUBJECT_PUBLIC_KEY: + if (object.len > 0 && *object.ptr == 0x00) + { + /* skip initial bit string octet defining 0 unused bits */ + object = chunk_skip(object, 1); + } + if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING, + parser->get_level(parser)+1, "blissPublicKey")) + { + goto end; + } + if (object.len != 2*this->set->n) + { + goto end; + } + this->a = bliss_public_key_from_asn1(object, this->set->n); + break; + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + if (!success) + { + destroy(this); + return NULL; + } + return &this->public; } diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c index df4b77cc3..35ea3e885 100644 --- a/src/libstrongswan/plugins/pem/pem_encoder.c +++ b/src/libstrongswan/plugins/pem/pem_encoder.c @@ -53,6 +53,11 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, break; } } + if (cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER, + &asn1, CRED_PART_END)) + { + break; + } return FALSE; case PRIVKEY_PEM: label ="RSA PRIVATE KEY"; @@ -86,6 +91,12 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, label ="EC PRIVATE KEY"; break; } + if (cred_encoding_args(args, CRED_PART_BLISS_PRIV_ASN1_DER, + &asn1, CRED_PART_END)) + { + label ="BLISS PRIVATE KEY"; + break; + } return FALSE; case CERT_PEM: if (cred_encoding_args(args, CRED_PART_X509_ASN1_DER, diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c index e7edd7b89..d5bcbb617 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.c +++ b/src/libstrongswan/plugins/pem/pem_plugin.c @@ -60,6 +60,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(PRIVKEY, KEY_DSA), PLUGIN_DEPENDS(PRIVKEY, KEY_DSA), PLUGIN_SDEPEND(HASHER, HASH_MD5), + PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS), + PLUGIN_DEPENDS(PRIVKEY, KEY_BLISS), /* public key PEM decoding */ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), @@ -74,6 +77,8 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_DSA), PLUGIN_DEPENDS(PUBKEY, KEY_DSA), + PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_BLISS), /* certificate PEM decoding */ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c index c6661fcda..767b3acf2 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c @@ -63,11 +63,18 @@ static public_key_t *parse_public_key(chunk_t blob) } else if (oid == OID_EC_PUBLICKEY) { - /* we need the whole subjectPublicKeyInfo for EC public keys */ + /* Need the whole subjectPublicKeyInfo for EC public keys */ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END); goto end; } + else if (oid == OID_BLISS_PUBLICKEY) + { + /* Need the whole subjectPublicKeyInfo for BLISS public keys */ + key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, + KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END); + goto end; + } else { /* key type not supported */ diff --git a/src/pki/commands/print.c b/src/pki/commands/print.c index a8a4e8375..fa69de133 100644 --- a/src/pki/commands/print.c +++ b/src/pki/commands/print.c @@ -32,9 +32,12 @@ static void print_pubkey(public_key_t *key) { chunk_t chunk; + key_type_t type; + + type = key->get_type(key); + printf("pubkey: %N %d bits%s\n", key_type_names, type, + key->get_keysize(key), (type == KEY_BLISS) ? " strength" : ""); - printf("pubkey: %N %d bits\n", key_type_names, key->get_type(key), - key->get_keysize(key)); if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &chunk)) { printf("keyid: %#B\n", &chunk); @@ -596,6 +599,11 @@ static int print() type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } + else if (streq(arg, "bliss-priv")) + { + type = CRED_PRIVATE_KEY; + subtype = KEY_BLISS; + } else { return command_usage( "invalid input type"); @@ -668,7 +676,7 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { print, 'a', "print", "print a credential in a human readable form", - {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl|ac]"}, + {"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|x509|crl|ac]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "input file, default: stdin"}, diff --git a/src/pki/commands/pub.c b/src/pki/commands/pub.c index b8d2f701d..843b784b4 100644 --- a/src/pki/commands/pub.c +++ b/src/pki/commands/pub.c @@ -53,6 +53,11 @@ static int pub() type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } + else if (streq(arg, "bliss")) + { + type = CRED_PRIVATE_KEY; + subtype = KEY_BLISS; + } else if (streq(arg, "pub")) { type = CRED_PUBLIC_KEY; @@ -183,7 +188,7 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { pub, 'p', "pub", "extract the public key from a private key/certificate", - {"[--in file|--keyid hex] [--type rsa|ecdsa|pub|pkcs10|x509]", + {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|pub|pkcs10|x509]", "[--outform der|pem|dnskey|sshkey]"}, { {"help", 'h', 0, "show usage information"}, |