aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2014-11-04 20:51:33 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2014-11-29 14:51:16 +0100
commit56009f2001a4678872c360d143fc3095803cb824 (patch)
tree1e217db0d9dc3447bf56bc34619611ea03190cb8
parent37bfe44358033639d6e87bf122def5a781cbf876 (diff)
downloadstrongswan-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.txt2
-rw-r--r--src/libstrongswan/credentials/cred_encoding.h4
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_private_key.c200
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_public_key.c221
-rw-r--r--src/libstrongswan/plugins/pem/pem_encoder.c11
-rw-r--r--src/libstrongswan/plugins/pem/pem_plugin.c5
-rw-r--r--src/libstrongswan/plugins/pkcs1/pkcs1_builder.c9
-rw-r--r--src/pki/commands/print.c14
-rw-r--r--src/pki/commands/pub.c7
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, &param);
+ if (oid != OID_BLISS_PUBLICKEY)
+ {
+ goto end;
+ }
+ if (!asn1_parse_simple_object(&param, 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"},