commit
c342cb5a21
@ -435,7 +435,7 @@ int dsa_shared_secret(void *private_key, void *base,
|
|||||||
#ifdef LTC_DER
|
#ifdef LTC_DER
|
||||||
/* DER handling */
|
/* DER handling */
|
||||||
|
|
||||||
enum {
|
typedef enum ltc_asn1_type_ {
|
||||||
LTC_ASN1_EOL,
|
LTC_ASN1_EOL,
|
||||||
LTC_ASN1_BOOLEAN,
|
LTC_ASN1_BOOLEAN,
|
||||||
LTC_ASN1_INTEGER,
|
LTC_ASN1_INTEGER,
|
||||||
@ -455,12 +455,12 @@ enum {
|
|||||||
LTC_ASN1_RAW_BIT_STRING,
|
LTC_ASN1_RAW_BIT_STRING,
|
||||||
LTC_ASN1_TELETEX_STRING,
|
LTC_ASN1_TELETEX_STRING,
|
||||||
LTC_ASN1_CONSTRUCTED,
|
LTC_ASN1_CONSTRUCTED,
|
||||||
};
|
} ltc_asn1_type;
|
||||||
|
|
||||||
/** A LTC ASN.1 list type */
|
/** A LTC ASN.1 list type */
|
||||||
typedef struct ltc_asn1_list_ {
|
typedef struct ltc_asn1_list_ {
|
||||||
/** The LTC ASN.1 enumerated type identifier */
|
/** The LTC ASN.1 enumerated type identifier */
|
||||||
int type;
|
ltc_asn1_type type;
|
||||||
/** The data to encode or place for decoding */
|
/** The data to encode or place for decoding */
|
||||||
void *data;
|
void *data;
|
||||||
/** The size of the input or resulting output */
|
/** The size of the input or resulting output */
|
||||||
|
@ -51,6 +51,16 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
|
|||||||
data = list[x].data;
|
data = list[x].data;
|
||||||
|
|
||||||
switch (list[x].type) {
|
switch (list[x].type) {
|
||||||
|
case LTC_ASN1_BOOLEAN:
|
||||||
|
if (der_decode_boolean(in, *inlen, data) == CRYPT_OK) {
|
||||||
|
if (der_length_boolean(&z) == CRYPT_OK) {
|
||||||
|
list[x].used = 1;
|
||||||
|
*inlen = z;
|
||||||
|
return CRYPT_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LTC_ASN1_INTEGER:
|
case LTC_ASN1_INTEGER:
|
||||||
if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
|
if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
|
||||||
if (der_length_integer(data, &z) == CRYPT_OK) {
|
if (der_length_integer(data, &z) == CRYPT_OK) {
|
||||||
@ -82,6 +92,17 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LTC_ASN1_RAW_BIT_STRING:
|
||||||
|
if (der_decode_raw_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
|
||||||
|
if (der_length_bit_string(size, &z) == CRYPT_OK) {
|
||||||
|
list[x].used = 1;
|
||||||
|
list[x].size = size;
|
||||||
|
*inlen = z;
|
||||||
|
return CRYPT_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LTC_ASN1_OCTET_STRING:
|
case LTC_ASN1_OCTET_STRING:
|
||||||
if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
|
if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
|
||||||
if (der_length_octet_string(size, &z) == CRYPT_OK) {
|
if (der_length_octet_string(size, &z) == CRYPT_OK) {
|
||||||
@ -112,6 +133,17 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
|
if (der_decode_teletex_string(in, *inlen, data, &size) == CRYPT_OK) {
|
||||||
|
if (der_length_teletex_string(data, size, &z) == CRYPT_OK) {
|
||||||
|
list[x].used = 1;
|
||||||
|
list[x].size = size;
|
||||||
|
*inlen = z;
|
||||||
|
return CRYPT_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LTC_ASN1_IA5_STRING:
|
case LTC_ASN1_IA5_STRING:
|
||||||
if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
|
if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
|
||||||
if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
|
if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
|
||||||
@ -166,7 +198,9 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case LTC_ASN1_CHOICE:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
|
case LTC_ASN1_EOL:
|
||||||
return CRYPT_INVALID_ARG;
|
return CRYPT_INVALID_ARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
||||||
ltc_asn1_list *list, unsigned long outlen, int ordered)
|
ltc_asn1_list *list, unsigned long outlen, int ordered)
|
||||||
{
|
{
|
||||||
int err, type, i;
|
int err, i;
|
||||||
|
ltc_asn1_type type;
|
||||||
unsigned long size, x, y, z, blksize;
|
unsigned long size, x, y, z, blksize;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
@ -187,6 +188,18 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
|
z = inlen;
|
||||||
|
if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) {
|
||||||
|
if (!ordered) { continue; }
|
||||||
|
goto LBL_ERR;
|
||||||
|
}
|
||||||
|
list[i].size = size;
|
||||||
|
if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) {
|
||||||
|
goto LBL_ERR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LTC_ASN1_IA5_STRING:
|
case LTC_ASN1_IA5_STRING:
|
||||||
z = inlen;
|
z = inlen;
|
||||||
if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
|
if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
|
||||||
@ -270,7 +283,8 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
|
case LTC_ASN1_EOL:
|
||||||
err = CRYPT_INVALID_ARG;
|
err = CRYPT_INVALID_ARG;
|
||||||
goto LBL_ERR;
|
goto LBL_ERR;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
|
|||||||
ltc_asn1_list *l;
|
ltc_asn1_list *l;
|
||||||
unsigned long err, type, len, totlen, x, y;
|
unsigned long err, type, len, totlen, x, y;
|
||||||
void *realloc_tmp;
|
void *realloc_tmp;
|
||||||
int isConstructed;
|
int is_constructed;
|
||||||
|
|
||||||
LTC_ARGCHK(in != NULL);
|
LTC_ARGCHK(in != NULL);
|
||||||
LTC_ARGCHK(inlen != NULL);
|
LTC_ARGCHK(inlen != NULL);
|
||||||
@ -103,12 +103,16 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
|
|||||||
l = l->next;
|
l = l->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isConstructed = ((type & 0xE0) == 0xA0 ? 1 : 0))) {
|
if ((type & 0x20) && (type != 0x30) && (type != 0x31)) {
|
||||||
|
is_constructed = 1;
|
||||||
/* constructed, use the 'used' field to store the original tag number */
|
/* constructed, use the 'used' field to store the original tag number */
|
||||||
l->used = (type & 0x1F);
|
l->used = (type & 0x1F);
|
||||||
/* treat constructed elements like SETs */
|
/* treat constructed elements like SETs */
|
||||||
type = 0x31;
|
type = 0x31;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
is_constructed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* now switch on type */
|
/* now switch on type */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -332,7 +336,15 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
|
|||||||
case 0x31: /* SET */
|
case 0x31: /* SET */
|
||||||
|
|
||||||
/* init field */
|
/* init field */
|
||||||
l->type = (isConstructed ? LTC_ASN1_CONSTRUCTED : ((type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET));
|
if (is_constructed) {
|
||||||
|
l->type = LTC_ASN1_CONSTRUCTED;
|
||||||
|
}
|
||||||
|
else if (type == 0x30) {
|
||||||
|
l->type = LTC_ASN1_SEQUENCE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
l->type = LTC_ASN1_SET;
|
||||||
|
}
|
||||||
|
|
||||||
/* we have to decode the SEQUENCE header and get it's length */
|
/* we have to decode the SEQUENCE header and get it's length */
|
||||||
|
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
*/
|
*/
|
||||||
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||||
{
|
{
|
||||||
int err, type;
|
int err;
|
||||||
|
ltc_asn1_type type;
|
||||||
unsigned long size, x;
|
unsigned long size, x;
|
||||||
void *data;
|
void *data;
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -40,7 +41,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
|||||||
va_start(args, inlen);
|
va_start(args, inlen);
|
||||||
x = 0;
|
x = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
type = va_arg(args, int);
|
type = va_arg(args, ltc_asn1_type);
|
||||||
size = va_arg(args, unsigned long);
|
size = va_arg(args, unsigned long);
|
||||||
data = va_arg(args, void*);
|
data = va_arg(args, void*);
|
||||||
|
|
||||||
@ -64,10 +65,13 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
|||||||
case LTC_ASN1_SETOF:
|
case LTC_ASN1_SETOF:
|
||||||
case LTC_ASN1_SEQUENCE:
|
case LTC_ASN1_SEQUENCE:
|
||||||
case LTC_ASN1_CHOICE:
|
case LTC_ASN1_CHOICE:
|
||||||
|
case LTC_ASN1_RAW_BIT_STRING:
|
||||||
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
++x;
|
++x;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case LTC_ASN1_EOL:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return CRYPT_INVALID_ARG;
|
return CRYPT_INVALID_ARG;
|
||||||
}
|
}
|
||||||
@ -88,7 +92,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
|||||||
va_start(args, inlen);
|
va_start(args, inlen);
|
||||||
x = 0;
|
x = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
type = va_arg(args, int);
|
type = va_arg(args, ltc_asn1_type);
|
||||||
size = va_arg(args, unsigned long);
|
size = va_arg(args, unsigned long);
|
||||||
data = va_arg(args, void*);
|
data = va_arg(args, void*);
|
||||||
|
|
||||||
@ -112,21 +116,18 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
|||||||
case LTC_ASN1_SET:
|
case LTC_ASN1_SET:
|
||||||
case LTC_ASN1_SETOF:
|
case LTC_ASN1_SETOF:
|
||||||
case LTC_ASN1_CHOICE:
|
case LTC_ASN1_CHOICE:
|
||||||
list[x].type = type;
|
case LTC_ASN1_RAW_BIT_STRING:
|
||||||
list[x].size = size;
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
list[x++].data = data;
|
LTC_SET_ASN1(list, x++, type, data, size);
|
||||||
|
break;
|
||||||
|
case LTC_ASN1_EOL:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
va_end(args);
|
|
||||||
err = CRYPT_INVALID_ARG;
|
|
||||||
goto LBL_ERR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
err = der_decode_sequence(in, inlen, list, x);
|
err = der_decode_sequence(in, inlen, list, x);
|
||||||
LBL_ERR:
|
|
||||||
XFREE(list);
|
XFREE(list);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in
|
|||||||
|
|
||||||
LTC_ARGCHK(in != NULL);
|
LTC_ARGCHK(in != NULL);
|
||||||
LTC_ARGCHK(inlen != 0);
|
LTC_ARGCHK(inlen != 0);
|
||||||
|
LTC_ARGCHK(public_key_len != NULL);
|
||||||
|
|
||||||
err = pk_get_oid(algorithm, &oid);
|
err = pk_get_oid(algorithm, &oid);
|
||||||
if (err != CRYPT_OK) {
|
if (err != CRYPT_OK) {
|
||||||
@ -63,8 +64,8 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in
|
|||||||
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
|
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);
|
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
|
/* the actual format of the SSL DER key is odd, it stores a RSAPublicKey
|
||||||
then proceed to convert bit to octet
|
* 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, 0, LTC_ASN1_SEQUENCE, alg_id, 2);
|
||||||
LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
|
LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
|
||||||
@ -74,6 +75,13 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in
|
|||||||
goto LBL_ERR;
|
goto LBL_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((alg_id[0].size != oid.OIDlen) ||
|
||||||
|
memcmp(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) {
|
||||||
|
/* OID mismatch */
|
||||||
|
err = CRYPT_PK_INVALID_TYPE;
|
||||||
|
goto LBL_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
len = subject_pubkey[1].size/8;
|
len = subject_pubkey[1].size/8;
|
||||||
if (*public_key_len > len) {
|
if (*public_key_len > len) {
|
||||||
memcpy(public_key, subject_pubkey[1].data, len);
|
memcpy(public_key, subject_pubkey[1].data, len);
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
|
int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
|
||||||
unsigned char *out, unsigned long *outlen, int type_of)
|
unsigned char *out, unsigned long *outlen, int type_of)
|
||||||
{
|
{
|
||||||
int err, type;
|
int err;
|
||||||
|
ltc_asn1_type type;
|
||||||
unsigned long size, x, y, z, i;
|
unsigned long size, x, y, z, i;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
@ -135,7 +136,10 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
|
|||||||
y += x;
|
y += x;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case LTC_ASN1_CHOICE:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
|
case LTC_ASN1_EOL:
|
||||||
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
err = CRYPT_INVALID_ARG;
|
err = CRYPT_INVALID_ARG;
|
||||||
goto LBL_ERR;
|
goto LBL_ERR;
|
||||||
}
|
}
|
||||||
@ -330,7 +334,10 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
|
|||||||
*outlen -= z;
|
*outlen -= z;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case LTC_ASN1_CHOICE:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
|
case LTC_ASN1_EOL:
|
||||||
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
err = CRYPT_INVALID_ARG;
|
err = CRYPT_INVALID_ARG;
|
||||||
goto LBL_ERR;
|
goto LBL_ERR;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
*/
|
*/
|
||||||
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||||
{
|
{
|
||||||
int err, type;
|
int err;
|
||||||
|
ltc_asn1_type type;
|
||||||
unsigned long size, x;
|
unsigned long size, x;
|
||||||
void *data;
|
void *data;
|
||||||
va_list args;
|
va_list args;
|
||||||
@ -41,7 +42,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
|||||||
va_start(args, outlen);
|
va_start(args, outlen);
|
||||||
x = 0;
|
x = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
type = va_arg(args, int);
|
type = va_arg(args, ltc_asn1_type);
|
||||||
size = va_arg(args, unsigned long);
|
size = va_arg(args, unsigned long);
|
||||||
data = va_arg(args, void*);
|
data = va_arg(args, void*);
|
||||||
|
|
||||||
@ -68,7 +69,10 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
|||||||
++x;
|
++x;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case LTC_ASN1_CHOICE:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
|
case LTC_ASN1_EOL:
|
||||||
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return CRYPT_INVALID_ARG;
|
return CRYPT_INVALID_ARG;
|
||||||
}
|
}
|
||||||
@ -89,7 +93,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
|||||||
va_start(args, outlen);
|
va_start(args, outlen);
|
||||||
x = 0;
|
x = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
type = va_arg(args, int);
|
type = va_arg(args, ltc_asn1_type);
|
||||||
size = va_arg(args, unsigned long);
|
size = va_arg(args, unsigned long);
|
||||||
data = va_arg(args, void*);
|
data = va_arg(args, void*);
|
||||||
|
|
||||||
@ -113,12 +117,13 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
|||||||
case LTC_ASN1_SET:
|
case LTC_ASN1_SET:
|
||||||
case LTC_ASN1_SETOF:
|
case LTC_ASN1_SETOF:
|
||||||
case LTC_ASN1_RAW_BIT_STRING:
|
case LTC_ASN1_RAW_BIT_STRING:
|
||||||
list[x].type = type;
|
LTC_SET_ASN1(list, x++, type, data, size);
|
||||||
list[x].size = size;
|
|
||||||
list[x++].data = data;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case LTC_ASN1_CHOICE:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
|
case LTC_ASN1_EOL:
|
||||||
|
case LTC_ASN1_TELETEX_STRING:
|
||||||
va_end(args);
|
va_end(args);
|
||||||
err = CRYPT_INVALID_ARG;
|
err = CRYPT_INVALID_ARG;
|
||||||
goto LBL_ERR;
|
goto LBL_ERR;
|
||||||
|
@ -49,13 +49,8 @@ int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
alg_id[0].data = oid.OID;
|
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen);
|
||||||
alg_id[0].size = oid.OIDlen;
|
LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len);
|
||||||
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,
|
return der_encode_sequence_multi(out, outlen,
|
||||||
LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
|
LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
|
||||||
|
@ -18,35 +18,40 @@
|
|||||||
#ifdef LTC_DER
|
#ifdef LTC_DER
|
||||||
|
|
||||||
/* LTC define to ASN.1 TAG */
|
/* LTC define to ASN.1 TAG */
|
||||||
static int ltc_to_asn1(int v)
|
static int ltc_to_asn1(ltc_asn1_type v)
|
||||||
{
|
{
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case LTC_ASN1_BOOLEAN: return 0x01;
|
case LTC_ASN1_BOOLEAN: return 0x01;
|
||||||
case LTC_ASN1_INTEGER:
|
case LTC_ASN1_INTEGER:
|
||||||
case LTC_ASN1_SHORT_INTEGER: return 0x02;
|
case LTC_ASN1_SHORT_INTEGER: return 0x02;
|
||||||
|
case LTC_ASN1_RAW_BIT_STRING:
|
||||||
case LTC_ASN1_BIT_STRING: return 0x03;
|
case LTC_ASN1_BIT_STRING: return 0x03;
|
||||||
case LTC_ASN1_OCTET_STRING: return 0x04;
|
case LTC_ASN1_OCTET_STRING: return 0x04;
|
||||||
case LTC_ASN1_NULL: return 0x05;
|
case LTC_ASN1_NULL: return 0x05;
|
||||||
case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06;
|
case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06;
|
||||||
case LTC_ASN1_UTF8_STRING: return 0x0C;
|
case LTC_ASN1_UTF8_STRING: return 0x0C;
|
||||||
case LTC_ASN1_PRINTABLE_STRING: return 0x13;
|
case LTC_ASN1_PRINTABLE_STRING: return 0x13;
|
||||||
|
case LTC_ASN1_TELETEX_STRING: return 0x14;
|
||||||
case LTC_ASN1_IA5_STRING: return 0x16;
|
case LTC_ASN1_IA5_STRING: return 0x16;
|
||||||
case LTC_ASN1_UTCTIME: return 0x17;
|
case LTC_ASN1_UTCTIME: return 0x17;
|
||||||
case LTC_ASN1_SEQUENCE: return 0x30;
|
case LTC_ASN1_SEQUENCE: return 0x30;
|
||||||
case LTC_ASN1_SET:
|
case LTC_ASN1_SET:
|
||||||
case LTC_ASN1_SETOF: return 0x31;
|
case LTC_ASN1_SETOF: return 0x31;
|
||||||
default: return -1;
|
case LTC_ASN1_CHOICE:
|
||||||
|
case LTC_ASN1_CONSTRUCTED:
|
||||||
|
case LTC_ASN1_EOL: return -1;
|
||||||
}
|
}
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qsort_helper(const void *a, const void *b)
|
static int qsort_helper(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
|
ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type);
|
r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type);
|
||||||
|
|
||||||
/* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */
|
/* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
/* their order in the original list now determines the position */
|
/* their order in the original list now determines the position */
|
||||||
@ -54,13 +59,13 @@ static int qsort_helper(const void *a, const void *b)
|
|||||||
} else {
|
} else {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Encode a SET type
|
Encode a SET type
|
||||||
@param list The list of items to encode
|
@param list The list of items to encode
|
||||||
@param inlen The number of items in the list
|
@param inlen The number of items in the list
|
||||||
@param out [out] The destination
|
@param out [out] The destination
|
||||||
@param outlen [in/out] The size of the output
|
@param outlen [in/out] The size of the output
|
||||||
@return CRYPT_OK on success
|
@return CRYPT_OK on success
|
||||||
*/
|
*/
|
||||||
@ -70,30 +75,30 @@ int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
|
|||||||
ltc_asn1_list *copy;
|
ltc_asn1_list *copy;
|
||||||
unsigned long x;
|
unsigned long x;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* make copy of list */
|
/* make copy of list */
|
||||||
copy = XCALLOC(inlen, sizeof(*copy));
|
copy = XCALLOC(inlen, sizeof(*copy));
|
||||||
if (copy == NULL) {
|
if (copy == NULL) {
|
||||||
return CRYPT_MEM;
|
return CRYPT_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in used member with index so we can fully sort it */
|
/* fill in used member with index so we can fully sort it */
|
||||||
for (x = 0; x < inlen; x++) {
|
for (x = 0; x < inlen; x++) {
|
||||||
copy[x] = list[x];
|
copy[x] = list[x];
|
||||||
copy[x].used = x;
|
copy[x].used = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sort it by the "type" field */
|
/* sort it by the "type" field */
|
||||||
XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);
|
XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);
|
||||||
|
|
||||||
/* call der_encode_sequence_ex() */
|
/* call der_encode_sequence_ex() */
|
||||||
err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);
|
err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);
|
||||||
|
|
||||||
/* free list */
|
/* free list */
|
||||||
XFREE(copy);
|
XFREE(copy);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,7 +40,7 @@ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
|
|||||||
return CRYPT_INVALID_PACKET;
|
return CRYPT_INVALID_PACKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for 0x13 */
|
/* check for 0x14 */
|
||||||
if ((in[0] & 0x1F) != 0x14) {
|
if ((in[0] & 0x1F) != 0x14) {
|
||||||
return CRYPT_INVALID_PACKET;
|
return CRYPT_INVALID_PACKET;
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ int der_decode_teletex_string(const unsigned char *in, unsigned long inlen,
|
|||||||
|
|
||||||
return CRYPT_OK;
|
return CRYPT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* $Source$ */
|
/* $Source$ */
|
||||||
|
@ -22,7 +22,6 @@ static void der_set_test(void)
|
|||||||
|
|
||||||
unsigned char strs[10][10], outbuf[128];
|
unsigned char strs[10][10], outbuf[128];
|
||||||
unsigned long x, val, outlen;
|
unsigned long x, val, outlen;
|
||||||
int err;
|
|
||||||
|
|
||||||
/* make structure and encode it */
|
/* make structure and encode it */
|
||||||
LTC_SET_ASN1(list, 0, LTC_ASN1_OCTET_STRING, oct_str, sizeof(oct_str));
|
LTC_SET_ASN1(list, 0, LTC_ASN1_OCTET_STRING, oct_str, sizeof(oct_str));
|
||||||
@ -31,21 +30,14 @@ static void der_set_test(void)
|
|||||||
|
|
||||||
/* encode it */
|
/* encode it */
|
||||||
outlen = sizeof(outbuf);
|
outlen = sizeof(outbuf);
|
||||||
if ((err = der_encode_set(list, 3, outbuf, &outlen)) != CRYPT_OK) {
|
DO(der_encode_set(list, 3, outbuf, &outlen));
|
||||||
fprintf(stderr, "error encoding set: %s\n", error_to_string(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* first let's test the set_decoder out of order to see what happens, we should get all the fields we expect even though they're in a diff order */
|
/* first let's test the set_decoder out of order to see what happens, we should get all the fields we expect even though they're in a diff order */
|
||||||
LTC_SET_ASN1(list, 0, LTC_ASN1_BIT_STRING, strs[1], sizeof(strs[1]));
|
LTC_SET_ASN1(list, 0, LTC_ASN1_BIT_STRING, strs[1], sizeof(strs[1]));
|
||||||
LTC_SET_ASN1(list, 1, LTC_ASN1_SHORT_INTEGER, &val, 1);
|
LTC_SET_ASN1(list, 1, LTC_ASN1_SHORT_INTEGER, &val, 1);
|
||||||
LTC_SET_ASN1(list, 2, LTC_ASN1_OCTET_STRING, strs[0], sizeof(strs[0]));
|
LTC_SET_ASN1(list, 2, LTC_ASN1_OCTET_STRING, strs[0], sizeof(strs[0]));
|
||||||
|
|
||||||
if ((err = der_decode_set(outbuf, outlen, list, 3)) != CRYPT_OK) {
|
DO(der_decode_set(outbuf, outlen, list, 3));
|
||||||
fprintf(stderr, "error decoding set using der_decode_set: %s\n", error_to_string(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now compare the items */
|
/* now compare the items */
|
||||||
if (memcmp(strs[0], oct_str, sizeof(oct_str))) {
|
if (memcmp(strs[0], oct_str, sizeof(oct_str))) {
|
||||||
@ -79,20 +71,14 @@ static void der_set_test(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
outlen = sizeof(outbuf);
|
outlen = sizeof(outbuf);
|
||||||
if ((err = der_encode_setof(list, 10, outbuf, &outlen)) != CRYPT_OK) {
|
DO(der_encode_setof(list, 10, outbuf, &outlen));
|
||||||
fprintf(stderr, "error encoding SET OF: %s\n", error_to_string(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = 0; x < 10; x++) {
|
for (x = 0; x < 10; x++) {
|
||||||
LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], sizeof(strs[x]) - 1);
|
LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], sizeof(strs[x]) - 1);
|
||||||
}
|
}
|
||||||
XMEMSET(strs, 0, sizeof(strs));
|
XMEMSET(strs, 0, sizeof(strs));
|
||||||
|
|
||||||
if ((err = der_decode_set(outbuf, outlen, list, 10)) != CRYPT_OK) {
|
DO(der_decode_set(outbuf, outlen, list, 10));
|
||||||
fprintf(stderr, "error decoding SET OF: %s\n", error_to_string(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now compare */
|
/* now compare */
|
||||||
for (x = 1; x < 10; x++) {
|
for (x = 1; x < 10; x++) {
|
||||||
@ -143,7 +129,6 @@ static void der_flexi_test(void)
|
|||||||
|
|
||||||
unsigned char encode_buf[192];
|
unsigned char encode_buf[192];
|
||||||
unsigned long encode_buf_len, decode_len;
|
unsigned long encode_buf_len, decode_len;
|
||||||
int err;
|
|
||||||
|
|
||||||
ltc_asn1_list static_list[5][3], *decoded_list, *l;
|
ltc_asn1_list static_list[5][3], *decoded_list, *l;
|
||||||
|
|
||||||
@ -169,10 +154,7 @@ static void der_flexi_test(void)
|
|||||||
|
|
||||||
/* encode it */
|
/* encode it */
|
||||||
encode_buf_len = sizeof(encode_buf);
|
encode_buf_len = sizeof(encode_buf);
|
||||||
if ((err = der_encode_sequence(&static_list[0][0], 3, encode_buf, &encode_buf_len)) != CRYPT_OK) {
|
DO(der_encode_sequence(&static_list[0][0], 3, encode_buf, &encode_buf_len));
|
||||||
fprintf(stderr, "Encoding static_list: %s\n", error_to_string(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
@ -185,10 +167,7 @@ static void der_flexi_test(void)
|
|||||||
|
|
||||||
/* decode with flexi */
|
/* decode with flexi */
|
||||||
decode_len = encode_buf_len;
|
decode_len = encode_buf_len;
|
||||||
if ((err = der_decode_sequence_flexi(encode_buf, &decode_len, &decoded_list)) != CRYPT_OK) {
|
DO(der_decode_sequence_flexi(encode_buf, &decode_len, &decoded_list));
|
||||||
fprintf(stderr, "decoding static_list: %s\n", error_to_string(err));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decode_len != encode_buf_len) {
|
if (decode_len != encode_buf_len) {
|
||||||
fprintf(stderr, "Decode len of %lu does not match encode len of %lu \n", decode_len, encode_buf_len);
|
fprintf(stderr, "Decode len of %lu does not match encode len of %lu \n", decode_len, encode_buf_len);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user