diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-07-19 20:10:26 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-07-19 20:10:26 +0200 |
commit | 56eb45f752baa978a9ea3573faee44857678597d (patch) | |
tree | 3c7da78ba84669d0f988b98450e4e55779dfcb41 | |
parent | 035b7bf3544ab9927dc2d64cf1e3214237ff0f71 (diff) | |
download | cryptodev-linux-56eb45f752baa978a9ea3573faee44857678597d.tar.gz cryptodev-linux-56eb45f752baa978a9ea3573faee44857678597d.tar.xz cryptodev-linux-56eb45f752baa978a9ea3573faee44857678597d.zip |
Public Keys are being exported to SubjectPublicKeyInfo format, instead of custom formats. For RSA keys the PKCS #1 format can be used as well.
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | examples/pk.c | 115 | ||||
-rw-r--r-- | libtomcrypt/headers/tomcrypt_hash.h | 6 | ||||
-rw-r--r-- | libtomcrypt/headers/tomcrypt_pk.h | 23 | ||||
-rw-r--r-- | libtomcrypt/misc/pk_get_oid.c | 40 | ||||
-rw-r--r-- | libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c | 8 | ||||
-rw-r--r-- | libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c | 7 | ||||
-rw-r--r-- | libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c | 97 | ||||
-rw-r--r-- | libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c | 69 | ||||
-rw-r--r-- | libtomcrypt/pk/dsa/dsa_export.c | 41 | ||||
-rw-r--r-- | libtomcrypt/pk/dsa/dsa_import.c | 49 | ||||
-rw-r--r-- | libtomcrypt/pk/rsa/rsa_export.c | 23 | ||||
-rw-r--r-- | libtomcrypt/pk/rsa/rsa_import.c | 43 |
13 files changed, 437 insertions, 88 deletions
@@ -62,7 +62,9 @@ TOMCRYPT_OBJECTS = libtomcrypt/misc/zeromem.o libtomcrypt/misc/crypt/crypt_argch libtomcrypt/pk/rsa/rsa_make_key.o libtomcrypt/pk/rsa/rsa_sign_hash.o libtomcrypt/pk/rsa/rsa_verify_hash.o \ libtomcrypt/pk/pkcs1/pkcs_1_i2osp.o libtomcrypt/pk/pkcs1/pkcs_1_mgf1.o libtomcrypt/pk/pkcs1/pkcs_1_oaep_decode.o \ libtomcrypt/pk/pkcs1/pkcs_1_oaep_encode.o libtomcrypt/pk/pkcs1/pkcs_1_os2ip.o libtomcrypt/pk/pkcs1/pkcs_1_pss_decode.o \ - libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.o libtomcrypt/pk/pkcs1/pkcs_1_v1_5_decode.o libtomcrypt/pk/pkcs1/pkcs_1_v1_5_encode.o + libtomcrypt/pk/pkcs1/pkcs_1_pss_encode.o libtomcrypt/pk/pkcs1/pkcs_1_v1_5_decode.o libtomcrypt/pk/pkcs1/pkcs_1_v1_5_encode.o \ + libtomcrypt/misc/pk_get_oid.o libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.o \ + libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.o cryptodev-objs = cryptodev_main.o cryptodev_cipher.o ncr.o \ ncr-data.o ncr-key.o ncr-limits.o ncr-sessions.o ncr-pk.o \ diff --git a/examples/pk.c b/examples/pk.c index d3445d4..0765638 100644 --- a/examples/pk.c +++ b/examples/pk.c @@ -16,6 +16,9 @@ #include <stdlib.h> #include <gnutls/gnutls.h> #include <gnutls/x509.h> +#if GNUTLS_VERSION_NUMBER >= 0x020b00 +# include <gnutls/abstract.h> +#endif #define DATA_SIZE 4096 @@ -107,7 +110,7 @@ int privkey_info (void* data, int data_size, int verbose) gnutls_x509_privkey_t key; size_t size; int ret; - gnutls_datum_t pem; + gnutls_datum_t der; unsigned char buffer[5*1024]; const char *cprint; @@ -117,10 +120,10 @@ int privkey_info (void* data, int data_size, int verbose) return 1; } - pem.data = data; - pem.size = data_size; + der.data = data; + der.size = data_size; - ret = gnutls_x509_privkey_import (key, &pem, GNUTLS_X509_FMT_DER); + ret = gnutls_x509_privkey_import (key, &der, GNUTLS_X509_FMT_DER); if (ret < 0) { fprintf(stderr, "unable to import privkey\n"); return 1; @@ -141,11 +144,11 @@ int privkey_info (void* data, int data_size, int verbose) if (ret == GNUTLS_PK_RSA) { gnutls_datum_t m, e, d, p, q, u, exp1={NULL,0}, exp2={NULL,0}; - #if GNUTLS_VERSION_NUMBER >= 0x020b00 +#if GNUTLS_VERSION_NUMBER >= 0x020b00 ret = gnutls_x509_privkey_export_rsa_raw2 (key, &m, &e, &d, &p, &q, &u, &exp1, &exp2); - #else +#else ret = gnutls_x509_privkey_export_rsa_raw (key, &m, &e, &d, &p, &q, &u); - #endif +#endif if (ret < 0) fprintf (stderr, "Error in key RSA data export: %s\n", gnutls_strerror (ret)); @@ -204,10 +207,92 @@ int privkey_info (void* data, int data_size, int verbose) -int pubkey_info(void* data, int data_size) +int pubkey_info(void* data, int data_size, int verbose) { #if GNUTLS_VERSION_NUMBER >= 0x020b00 - /* XXX: use pubkey_t */ + gnutls_pubkey_t key; + size_t size; + int ret; + gnutls_datum_t der; + unsigned char buffer[5*1024]; + const char *cprint; + + ret = gnutls_pubkey_init (&key); + if (ret < 0) { + fprintf(stderr, "error in pubkey_init\n"); + return 1; + } + + der.data = data; + der.size = data_size; + + ret = gnutls_pubkey_import (key, &der, GNUTLS_X509_FMT_DER); + if (ret < 0) { + fprintf(stderr, "unable to import pubkey\n"); + return 1; + } + + if (verbose > 0) { + /* Public key algorithm + */ + fprintf (stdout, "Public Key Info:\n"); + ret = gnutls_pubkey_get_pk_algorithm (key, NULL); + + fprintf (stdout, "\tPublic Key Algorithm: "); + cprint = gnutls_pk_algorithm_get_name (ret); + fprintf (stdout, "%s\n", cprint ? cprint : "Unknown"); + + /* Print the raw public and private keys + */ + if (ret == GNUTLS_PK_RSA) { + gnutls_datum_t m, e; + + ret = gnutls_pubkey_get_pk_rsa_raw (key, &m, &e); + if (ret < 0) + fprintf (stderr, "Error in key RSA data export: %s\n", + gnutls_strerror (ret)); + else { + print_rsa_pkey (&m, &e, NULL, NULL, NULL, NULL, NULL, NULL); + gnutls_free (m.data); + gnutls_free (e.data); + } + } else if (ret == GNUTLS_PK_DSA) { + gnutls_datum_t p, q, g, y; + + ret = gnutls_pubkey_get_pk_dsa_raw (key, &p, &q, &g, &y); + if (ret < 0) + fprintf (stderr, "Error in key DSA data export: %s\n", + gnutls_strerror (ret)); + else { + print_dsa_pkey (NULL, &y, &p, &q, &g); + gnutls_free (y.data); + gnutls_free (p.data); + gnutls_free (q.data); + gnutls_free (g.data); + } + } + + fprintf (stdout, "\n"); + + size = sizeof (buffer); + if ((ret = gnutls_pubkey_get_key_id (key, 0, buffer, &size)) < 0) { + fprintf (stderr, "Error in key id calculation: %s\n", + gnutls_strerror (ret)); + } else { + fprintf (stdout, "Public Key ID: %s\n", raw_to_string (buffer, size)); + } + + size = sizeof (buffer); + ret = gnutls_pubkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &size); + if (ret < 0) { + fprintf(stderr, "Error in privkey_export\n"); + return 1; + } + + fprintf (stdout, "\n%s\n", buffer); + } + + gnutls_pubkey_deinit (key); #endif return 0; } @@ -599,8 +684,8 @@ static int test_ncr_rsa(int cfd) return 1; } - ret = pubkey_info(kdata.data, kdata.data_size); - if (ret < 0) { + ret = pubkey_info(kdata.data, kdata.data_size, 0); + if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } @@ -743,8 +828,8 @@ static int test_ncr_dsa(int cfd) return 1; } - ret = pubkey_info(kdata.data, kdata.data_size); - if (ret < 0) { + ret = pubkey_info(kdata.data, kdata.data_size, 0); + if (ret != 0) { fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); return 1; } @@ -778,10 +863,10 @@ main() return 1; } - if (test_ncr_dsa(fd)) + if (test_ncr_rsa(fd)) return 1; - if (test_ncr_rsa(fd)) + if (test_ncr_dsa(fd)) return 1; /* Close the original descriptor */ diff --git a/libtomcrypt/headers/tomcrypt_hash.h b/libtomcrypt/headers/tomcrypt_hash.h index 5eaa97c..417e481 100644 --- a/libtomcrypt/headers/tomcrypt_hash.h +++ b/libtomcrypt/headers/tomcrypt_hash.h @@ -8,11 +8,5 @@ int hash_memory(int hash, int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...); -typedef struct Oid { - unsigned long OID[16]; - /** Length of DER encoding */ - unsigned long OIDlen; -} oid_st; - int hash_get_oid(int hash, oid_st* st); diff --git a/libtomcrypt/headers/tomcrypt_pk.h b/libtomcrypt/headers/tomcrypt_pk.h index c8279ff..fa6030e 100644 --- a/libtomcrypt/headers/tomcrypt_pk.h +++ b/libtomcrypt/headers/tomcrypt_pk.h @@ -5,6 +5,18 @@ enum { PK_PRIVATE=1 }; +enum { + PKA_RSA, + PKA_DSA +}; + +typedef struct Oid { + unsigned long OID[16]; + /** Length of DER encoding */ + unsigned long OIDlen; +} oid_st; + +int pk_get_oid(int pk, oid_st *st); int rand_prime(mp_int *N, long len); /* ---- RSA ---- */ @@ -210,12 +222,21 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, ltc_asn1_list *list, unsigned long outlen, int ordered); - + #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen); +/* SUBJECT PUBLIC KEY INFO */ +int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, + unsigned int algorithm, void* public_key, unsigned long public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len); + +int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); + /* SET */ #define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) #define der_length_set der_length_sequence diff --git a/libtomcrypt/misc/pk_get_oid.c b/libtomcrypt/misc/pk_get_oid.c new file mode 100644 index 0000000..197d7ae --- /dev/null +++ b/libtomcrypt/misc/pk_get_oid.c @@ -0,0 +1,40 @@ +/* LibTomCrypt, modular cryptographic library + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + */ +#include "tomcrypt.h" + +static const oid_st rsa_oid = { + .OIDlen = 7, + .OID = { 1, 2, 840, 113549, 1, 1, 1 }, +}; + +static const oid_st dsa_oid = { + .OIDlen = 6, + .OID = { 1, 2, 840, 10040, 4, 1 }, +}; + +/* + Returns the OID of the public key algorithm. + @return CRYPT_OK if valid +*/ +int pk_get_oid(int pk, oid_st *st) +{ + switch (pk) { + case PKA_RSA: + memcpy(st, &rsa_oid, sizeof(*st)); + break; + case PKA_DSA: + memcpy(st, &dsa_oid, sizeof(*st)); + break; + default: + return CRYPT_INVALID_ARG; + } + return CRYPT_OK; +} + diff --git a/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c b/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c index d126df3..c9f6368 100644 --- a/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c +++ b/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c @@ -18,11 +18,13 @@ #ifdef LTC_DER +#define setbit(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n)))) + /** Store a BIT STRING @param in The DER encoded BIT STRING @param inlen The size of the DER BIT STRING - @param out [out] The array of bits stored (one per char) + @param out [out] The array of bits stored (8 per char) @param outlen [in/out] The number of bits stored @return CRYPT_OK if successful */ @@ -84,7 +86,9 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, /* decode/store the bits */ for (y = 0; y < blen; y++) { - out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; + if (in[x] & (1 << (7 - (y & 7)))) { + setbit(out[y/8], 7-(y%8)); + } if ((y & 7) == 7) { ++x; } diff --git a/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c b/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c index d77ea5a..d1b6064 100644 --- a/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c +++ b/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c @@ -18,9 +18,11 @@ #ifdef LTC_DER +#define getbit(n, k) (((n) & ( 1 << (k) )) >> (k)) + /** Store a BIT STRING - @param in The array of bits to store (one per char) + @param in The array of bits to store (8 per char) @param inlen The number of bits tostore @param out [out] The destination for the DER encoded BIT STRING @param outlen [in/out] The max size and resulting size of the DER BIT STRING @@ -68,7 +70,7 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, /* store the bits in big endian format */ for (y = buf = 0; y < inlen; y++) { - buf |= (in[y] ? 1 : 0) << (7 - (y & 7)); + buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7)); if ((y & 7) == 7) { out[x++] = buf; buf = 0; @@ -78,6 +80,7 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, if (inlen & 7) { out[x++] = buf; } + *outlen = x; return CRYPT_OK; } diff --git a/libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c b/libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c new file mode 100644 index 0000000..6c97e96 --- /dev/null +++ b/libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c @@ -0,0 +1,97 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + */ +#include "tomcrypt.h" +/** + @file der_encode_sequence_multi.c + ASN.1 DER, encode a Subject Public Key structure --nmav +*/ + +#ifdef LTC_DER + +/* AlgorithmIdentifier := SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm + * } + * + * SubjectPublicKeyInfo := SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + */ +/** + Encode a SEQUENCE type using a VA list + @param out [out] Destination for data + @param outlen [in/out] Length of buffer and resulting length of output + @remark <...> is of the form <type, size, data> (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len) +{ + int err, len; + oid_st oid; + unsigned char *tmpbuf; + unsigned long tmpoid[16]; + ltc_asn1_list alg_id[2]; + ltc_asn1_list subject_pubkey[2]; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != 0); + + err = pk_get_oid(algorithm, &oid); + if (err != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + /* this includes the internal hash ID and optional params (NULL in this case) */ + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); + LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len); + + /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it + then proceed to convert bit to octet + */ + LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2); + LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8); + + err=der_decode_sequence(in, inlen, subject_pubkey, 2UL); + if (err != CRYPT_OK) { + goto LBL_ERR; + } + + len = subject_pubkey[1].size/8; + if (*public_key_len > len) { + memcpy(public_key, subject_pubkey[1].data, len); + *public_key_len = len; + } else { + *public_key_len = len; + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + err = CRYPT_OK; + +LBL_ERR: + + XFREE(tmpbuf); + + return err; +} + +#endif + + diff --git a/libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c b/libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c new file mode 100644 index 0000000..e37c4b4 --- /dev/null +++ b/libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c @@ -0,0 +1,69 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + */ +#include "tomcrypt.h" + +/** + @file der_encode_sequence_multi.c + ASN.1 DER, encode a Subject Public Key structure --nmav +*/ + +#ifdef LTC_DER + +/* AlgorithmIdentifier := SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm + * } + * + * SubjectPublicKeyInfo := SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + */ +/** + Encode a SEQUENCE type using a VA list + @param out [out] Destination for data + @param outlen [in/out] Length of buffer and resulting length of output + @remark <...> is of the form <type, size, data> (int, unsigned long, void*) + @return CRYPT_OK on success +*/ +int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, + unsigned int algorithm, void* public_key, unsigned long public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len) +{ + int err; + ltc_asn1_list alg_id[2]; + oid_st oid; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + err = pk_get_oid(algorithm, &oid); + if (err != CRYPT_OK) { + return err; + } + + alg_id[0].data = oid.OID; + alg_id[0].size = oid.OIDlen; + alg_id[0].type = LTC_ASN1_OBJECT_IDENTIFIER; + + alg_id[1].data = parameters; + alg_id[1].size = parameters_len; + alg_id[1].type = parameters_type; + + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id, + LTC_ASN1_BIT_STRING, (unsigned long)(public_key_len*8), public_key, + LTC_ASN1_EOL, 0UL, NULL); + +} + +#endif + + diff --git a/libtomcrypt/pk/dsa/dsa_export.c b/libtomcrypt/pk/dsa/dsa_export.c index 11b6638..1fef6c7 100644 --- a/libtomcrypt/pk/dsa/dsa_export.c +++ b/libtomcrypt/pk/dsa/dsa_export.c @@ -27,8 +27,8 @@ */ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) { - unsigned char flags[1]; unsigned long zero=0; + int err; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); @@ -43,8 +43,6 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key return CRYPT_INVALID_ARG; } - flags[0] = (type != PK_PUBLIC) ? 1 : 0; - /* This encoding is different from the one in original * libtomcrypt. It uses a compatible encoding with gnutls * and openssl @@ -59,13 +57,36 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key LTC_ASN1_INTEGER, 1UL, &key->x, LTC_ASN1_EOL, 0UL, NULL); } else { - return der_encode_sequence_multi(out, outlen, - LTC_ASN1_BIT_STRING, 1UL, flags, - LTC_ASN1_INTEGER, 1UL, &key->g, - LTC_ASN1_INTEGER, 1UL, &key->p, - LTC_ASN1_INTEGER, 1UL, &key->q, - LTC_ASN1_INTEGER, 1UL, &key->y, - LTC_ASN1_EOL, 0UL, NULL); + unsigned long tmplen = (mp_count_bits(&key->y)/8)+8; + unsigned char* tmp = XMALLOC(tmplen); + ltc_asn1_list int_list[3]; + + if (tmp == NULL) { + return CRYPT_MEM; + } + + err = der_encode_integer(&key->y, tmp, &tmplen); + if (err != CRYPT_OK) { + goto error; + } + + int_list[0].data = &key->p; + int_list[0].size = 1UL; + int_list[0].type = LTC_ASN1_INTEGER; + int_list[1].data = &key->q; + int_list[1].size = 1UL; + int_list[1].type = LTC_ASN1_INTEGER; + int_list[2].data = &key->g; + int_list[2].size = 1UL; + int_list[2].type = LTC_ASN1_INTEGER; + + err = der_encode_subject_public_key_info(out, outlen, + PKA_DSA, tmp, tmplen, + LTC_ASN1_SEQUENCE, int_list, sizeof(int_list)/sizeof(int_list[0])); + +error: + XFREE(tmp); + return err; } } diff --git a/libtomcrypt/pk/dsa/dsa_import.c b/libtomcrypt/pk/dsa/dsa_import.c index 88e74f5..c0680f5 100644 --- a/libtomcrypt/pk/dsa/dsa_import.c +++ b/libtomcrypt/pk/dsa/dsa_import.c @@ -26,9 +26,9 @@ */ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) { - unsigned char flags[1]; int err; unsigned long zero = 0; + unsigned char* tmpbuf = NULL; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); @@ -40,44 +40,55 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) /* get key type */ if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_BIT_STRING, 1UL, flags, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - /* private key */ - if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_SHORT_INTEGER, 1UL, &zero, LTC_ASN1_INTEGER, 1UL, &key->p, LTC_ASN1_INTEGER, 1UL, &key->q, LTC_ASN1_INTEGER, 1UL, &key->g, LTC_ASN1_INTEGER, 1UL, &key->y, LTC_ASN1_INTEGER, 1UL, &key->x, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto error; - } + LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { key->type = PK_PRIVATE; - } else { /* public */ + ltc_asn1_list params[3]; + unsigned long tmpbuf_len = MAX_RSA_SIZE*8; + + LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, &key->p, 1UL); + LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, &key->q, 1UL); + LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, &key->g, 1UL); + + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_BIT_STRING, 1UL, flags, - LTC_ASN1_INTEGER, 1UL, &key->g, - LTC_ASN1_INTEGER, 1UL, &key->p, - LTC_ASN1_INTEGER, 1UL, &key->q, - LTC_ASN1_INTEGER, 1UL, &key->y, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto error; + err = der_decode_subject_public_key_info(in, inlen, + PKA_DSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_SEQUENCE, params, 3); + if (err != CRYPT_OK) { + goto LBL_ERR; } + + if ((err=der_decode_integer(tmpbuf, tmpbuf_len, &key->y)) != CRYPT_OK) { + goto LBL_ERR; + } + + XFREE(tmpbuf); key->type = PK_PUBLIC; } + key->qord = mp_unsigned_bin_size(&key->q); if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || (unsigned long)key->qord >= mp_unsigned_bin_size(&key->p) || (mp_unsigned_bin_size(&key->p) - key->qord) >= LTC_MDSA_DELTA) { err = CRYPT_INVALID_PACKET; - goto error; + goto LBL_ERR; } return CRYPT_OK; -error: + +LBL_ERR: + XFREE(tmpbuf); mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL); return err; } diff --git a/libtomcrypt/pk/rsa/rsa_export.c b/libtomcrypt/pk/rsa/rsa_export.c index 04e59d8..33c222d 100644 --- a/libtomcrypt/pk/rsa/rsa_export.c +++ b/libtomcrypt/pk/rsa/rsa_export.c @@ -9,7 +9,7 @@ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" - +#include <ncr_int.h> /** @file rsa_export.c Export RSA LTC_PKCS keys, Tom St Denis @@ -28,6 +28,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) { unsigned long zero=0; + int err; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); @@ -54,11 +55,27 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key LTC_ASN1_INTEGER, 1UL, &key->qP, LTC_ASN1_EOL, 0UL, NULL); } else { - /* public key */ - return der_encode_sequence_multi(out, outlen, + unsigned long tmplen = (mp_count_bits(&key->N)/8)*2+8; + unsigned char* tmp = XMALLOC(tmplen); + + if (tmp == NULL) { + return CRYPT_MEM; + } + + err = der_encode_sequence_multi(tmp, &tmplen, LTC_ASN1_INTEGER, 1UL, &key->N, LTC_ASN1_INTEGER, 1UL, &key->e, LTC_ASN1_EOL, 0UL, NULL); + if (err != CRYPT_OK) { + goto error; + } + + err = der_encode_subject_public_key_info(out, outlen, + PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0); + +error: + XFREE(tmp); + return err; } } diff --git a/libtomcrypt/pk/rsa/rsa_import.c b/libtomcrypt/pk/rsa/rsa_import.c index db78236..2eaa0a9 100644 --- a/libtomcrypt/pk/rsa/rsa_import.c +++ b/libtomcrypt/pk/rsa/rsa_import.c @@ -28,10 +28,8 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { int err; mp_int zero; - unsigned char *tmpbuf; - unsigned long t, x, y, z, tmpoid[16]; - ltc_asn1_list ssl_pubkey_hashoid[2]; - ltc_asn1_list ssl_pubkey[2]; + unsigned char *tmpbuf=NULL; + unsigned long tmpbuf_len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); @@ -43,47 +41,33 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) } /* see if the OpenSSL DER format RSA public key will work */ - tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8); + tmpbuf_len = MAX_RSA_SIZE * 8; + tmpbuf = XCALLOC(1, tmpbuf_len); if (tmpbuf == NULL) { err = CRYPT_MEM; goto LBL_ERR; } - /* this includes the internal hash ID and optional params (NULL in this case) */ - LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); - LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0); - - /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it - then proceed to convert bit to octet - */ - LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2); - LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8); - - if (der_decode_sequence(in, inlen, - ssl_pubkey, 2UL) == CRYPT_OK) { - - /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */ - for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) { - y = (y << 1) | tmpbuf[x]; - if (++z == 8) { - tmpbuf[t++] = (unsigned char)y; - y = 0; - z = 0; - } - } + err = der_decode_subject_public_key_info(in, inlen, + PKA_RSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_NULL, NULL, 0); + + if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ /* now it should be SEQUENCE { INTEGER, INTEGER } */ - if ((err = der_decode_sequence_multi(tmpbuf, t, + if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, LTC_ASN1_INTEGER, 1UL, &key->N, LTC_ASN1_INTEGER, 1UL, &key->e, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - XFREE(tmpbuf); goto LBL_ERR; } + XFREE(tmpbuf); + key->type = PK_PUBLIC; return CRYPT_OK; } + XFREE(tmpbuf); /* not SSL public key, try to match against LTC_PKCS #1 standards */ @@ -130,6 +114,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) } return CRYPT_OK; LBL_ERR: + XFREE(tmpbuf); mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); return err; } |