RSA and DSA public keys are stored using the SubjectPublicKeyInfo format.
This commit is contained in:
parent
8c2850f8d9
commit
fa22e791d4
4
makefile
4
makefile
@ -143,6 +143,7 @@ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \
|
||||
src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \
|
||||
src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \
|
||||
src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \
|
||||
src/misc/pk_get_oid.o \
|
||||
src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \
|
||||
src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \
|
||||
src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \
|
||||
@ -173,6 +174,7 @@ src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o
|
||||
src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \
|
||||
src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \
|
||||
src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \
|
||||
src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_raw_bit_string.o \
|
||||
src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \
|
||||
src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \
|
||||
src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \
|
||||
@ -186,6 +188,8 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
|
||||
src/pk/asn1/der/printable_string/der_decode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_encode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_length_printable_string.o \
|
||||
src/pk/asn1/der/sequence/der_encode_subject_public_key_info.o \
|
||||
src/pk/asn1/der/sequence/der_decode_subject_public_key_info.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence_ex.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
|
||||
|
@ -7,6 +7,19 @@ enum {
|
||||
|
||||
int rand_prime(void *N, long len, prng_state *prng, int wprng);
|
||||
|
||||
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);
|
||||
|
||||
/* ---- RSA ---- */
|
||||
#ifdef LTC_MRSA
|
||||
|
||||
@ -429,7 +442,8 @@ enum {
|
||||
LTC_ASN1_CHOICE,
|
||||
LTC_ASN1_SEQUENCE,
|
||||
LTC_ASN1_SET,
|
||||
LTC_ASN1_SETOF
|
||||
LTC_ASN1_SETOF,
|
||||
LTC_ASN1_RAW_BIT_STRING,
|
||||
};
|
||||
|
||||
/** A LTC ASN.1 list type */
|
||||
@ -470,6 +484,15 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
||||
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
|
||||
@ -509,6 +532,10 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
|
||||
|
||||
/* OCTET STRING */
|
||||
|
39
src/misc/pk_get_oid.c
Normal file
39
src/misc/pk_get_oid.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* 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;
|
||||
}
|
106
src/pk/asn1/der/bit/der_decode_raw_bit_string.c
Normal file
106
src/pk/asn1/der/bit/der_decode_raw_bit_string.c
Normal file
@ -0,0 +1,106 @@
|
||||
/* 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.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file der_decode_bit_string.c
|
||||
ASN.1 DER, encode a BIT STRING, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#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 (8 per char)
|
||||
@param outlen [in/out] The number of bits stored
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long dlen, blen, x, y;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* packet must be at least 4 bytes */
|
||||
if (inlen < 4) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* check for 0x03 */
|
||||
if ((in[0]&0x1F) != 0x03) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* offset in the data */
|
||||
x = 1;
|
||||
|
||||
/* get the length of the data */
|
||||
if (in[x] & 0x80) {
|
||||
/* long format get number of length bytes */
|
||||
y = in[x++] & 0x7F;
|
||||
|
||||
/* invalid if 0 or > 2 */
|
||||
if (y == 0 || y > 2) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* read the data len */
|
||||
dlen = 0;
|
||||
while (y--) {
|
||||
dlen = (dlen << 8) | (unsigned long)in[x++];
|
||||
}
|
||||
} else {
|
||||
/* short format */
|
||||
dlen = in[x++] & 0x7F;
|
||||
}
|
||||
|
||||
/* is the data len too long or too short? */
|
||||
if ((dlen == 0) || (dlen + x > inlen)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* get padding count */
|
||||
blen = ((dlen - 1) << 3) - (in[x++] & 7);
|
||||
|
||||
/* too many bits? */
|
||||
if (blen > *outlen) {
|
||||
*outlen = blen;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* decode/store the bits */
|
||||
for (y = 0; y < blen; y++) {
|
||||
if (in[x] & (1 << (7 - (y & 7)))) {
|
||||
setbit(out[y/8], 7-(y%8));
|
||||
}
|
||||
if ((y & 7) == 7) {
|
||||
++x;
|
||||
}
|
||||
}
|
||||
|
||||
/* we done */
|
||||
*outlen = blen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */
|
||||
/* $Revision: 1.5 $ */
|
||||
/* $Date: 2006/12/28 01:27:24 $ */
|
92
src/pk/asn1/der/bit/der_encode_raw_bit_string.c
Normal file
92
src/pk/asn1/der/bit/der_encode_raw_bit_string.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* 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.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file der_encode_bit_string.c
|
||||
ASN.1 DER, encode a BIT STRING, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
#define getbit(n, k) (((n) & ( 1 << (k) )) >> (k))
|
||||
|
||||
/**
|
||||
Store a BIT STRING
|
||||
@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
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long len, x, y;
|
||||
unsigned char buf;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* avoid overflows */
|
||||
if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (len > *outlen) {
|
||||
*outlen = len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* store header (include bit padding count in length) */
|
||||
x = 0;
|
||||
y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
|
||||
|
||||
out[x++] = 0x03;
|
||||
if (y < 128) {
|
||||
out[x++] = (unsigned char)y;
|
||||
} else if (y < 256) {
|
||||
out[x++] = 0x81;
|
||||
out[x++] = (unsigned char)y;
|
||||
} else if (y < 65536) {
|
||||
out[x++] = 0x82;
|
||||
out[x++] = (unsigned char)((y>>8)&255);
|
||||
out[x++] = (unsigned char)(y&255);
|
||||
}
|
||||
|
||||
/* store number of zero padding bits */
|
||||
out[x++] = (unsigned char)((8 - inlen) & 7);
|
||||
|
||||
/* store the bits in big endian format */
|
||||
for (y = buf = 0; y < inlen; y++) {
|
||||
buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7));
|
||||
if ((y & 7) == 7) {
|
||||
out[x++] = buf;
|
||||
buf = 0;
|
||||
}
|
||||
}
|
||||
/* store last byte */
|
||||
if (inlen & 7) {
|
||||
out[x++] = buf;
|
||||
}
|
||||
|
||||
*outlen = x;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */
|
||||
/* $Revision: 1.5 $ */
|
||||
/* $Date: 2006/12/28 01:27:24 $ */
|
@ -139,6 +139,18 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
z = inlen;
|
||||
if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
|
||||
if (!ordered) { continue; }
|
||||
goto LBL_ERR;
|
||||
}
|
||||
list[i].size = size;
|
||||
if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
z = inlen;
|
||||
if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
|
||||
|
@ -0,0 +1,95 @@
|
||||
/* 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_RAW_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
|
@ -73,6 +73,7 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
|
||||
break;
|
||||
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
@ -233,6 +234,15 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
|
||||
*outlen -= z;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += z;
|
||||
*outlen -= z;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
|
@ -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_RAW_BIT_STRING, (unsigned long)(public_key_len*8), public_key,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -29,6 +29,7 @@ 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 +44,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
|
||||
@ -60,13 +59,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
@ -41,30 +41,41 @@ 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 */
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
@ -72,11 +83,12 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
@ -55,10 +56,29 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
} else {
|
||||
/* public key */
|
||||
return der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_INTEGER, 1UL, key->N,
|
||||
LTC_ASN1_INTEGER, 1UL, key->e,
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,8 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
|
||||
{
|
||||
int err;
|
||||
void *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);
|
||||
@ -44,41 +42,24 @@ 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);
|
||||
err = der_decode_subject_public_key_info(in, inlen,
|
||||
PKA_RSA, tmpbuf, &tmpbuf_len,
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */
|
||||
|
||||
/* now it should be SEQUENCE { INTEGER, INTEGER } */
|
||||
if ((err = der_decode_sequence_multi(tmpbuf, t,
|
||||
LTC_ASN1_INTEGER, 1UL, key->N,
|
||||
LTC_ASN1_INTEGER, 1UL, key->e,
|
||||
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);
|
||||
@ -131,6 +112,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user