diff options
author | Matt Johnston <matt@ucc.asn.au> | 2006-06-10 16:39:40 +0000 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2006-06-10 16:39:40 +0000 |
commit | c9d3c0bc90f21886e0b78595c53e748256e299bf (patch) | |
tree | 0bb2d3bf2f98dae918f07727f55a36d0a637b9f5 /libtomcrypt/src/pk/asn1 | |
parent | 94d86427ff20ed544e299d3a2de5ecc2cc04c191 (diff) | |
parent | 3b0e6a29698c8580b9556332e678e5301e697959 (diff) |
merge of 332f709a4cb39cde4cedab7c3be89e05f3023067
and ca4ca78b82c5d430c69ce01bf794e8886ce81431
--HG--
extra : convert_revision : 74020525425a1de06739c6c3bed9ef35e4ad867e
Diffstat (limited to 'libtomcrypt/src/pk/asn1')
30 files changed, 3346 insertions, 0 deletions
diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c new file mode 100644 index 0000000..da5b989 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c @@ -0,0 +1,101 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + 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 outlen [in/out] The number of bits stored + @return CRYPT_OK if successful +*/ +int der_decode_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++] & 127; + + /* 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++] & 127; + } + + /* 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) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode/store the bits */ + for (y = 0; y < blen; y++) { + out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; + 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.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c new file mode 100644 index 0000000..569c15b --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c @@ -0,0 +1,87 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The array of bits to store (one 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_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y, 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) { + 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++] = y; + } else if (y < 256) { + out[x++] = 0x81; + out[x++] = y; + } else if (y < 65536) { + out[x++] = 0x82; + out[x++] = (y>>8)&255; + out[x++] = y&255; + } + + /* store number of zero padding bits */ + out[x++] = (8 - inlen) & 7; + + /* store the bits in big endian format */ + for (y = buf = 0; y < inlen; y++) { + buf |= (in[y] ? 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.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c b/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c new file mode 100644 index 0000000..dd6ea6d --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c @@ -0,0 +1,54 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_bit_string.c + ASN.1 DER, get length of BIT STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of BIT STRING + @param nbits The number of bits in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_bit_string(unsigned long nbits, unsigned long *outlen) +{ + unsigned long nbytes; + LTC_ARGCHK(outlen != NULL); + + /* get the number of the bytes */ + nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; + + if (nbytes < 128) { + /* 03 LL PP DD DD DD ... */ + *outlen = 2 + nbytes; + } else if (nbytes < 256) { + /* 03 81 LL PP DD DD DD ... */ + *outlen = 3 + nbytes; + } else if (nbytes < 65536) { + /* 03 82 LL LL PP DD DD DD ... */ + *outlen = 4 + nbytes; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c b/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c new file mode 100644 index 0000000..61cba11 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c @@ -0,0 +1,168 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_choice.c + ASN.1 DER, decode a CHOICE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a CHOICE + @param in The DER encoded input + @param inlen [in/out] The size of the input and resulting size of read type + @param list The list of items to decode + @param outlen The number of items in the list + @return CRYPT_OK on success +*/ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen) +{ + unsigned long size, x, z; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (*inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* set all of the "used" flags to zero */ + for (x = 0; x < outlen; x++) { + list[x].used = 0; + } + + /* now scan until we have a winner */ + for (x = 0; x < outlen; x++) { + size = list[x].size; + data = list[x].data; + + switch (list[x].type) { + case LTC_ASN1_INTEGER: + if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_integer(data, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_SHORT_INTEGER: + if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { + if (der_length_short_integer(size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_BIT_STRING: + if (der_decode_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: + if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_octet_string(size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_NULL: + if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { + *inlen = 2; + return CRYPT_OK; + } + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_IA5_STRING: + if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + + case LTC_ASN1_PRINTABLE_STRING: + if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { + if (der_length_printable_string(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + list[x].size = size; + *inlen = z; + return CRYPT_OK; + } + } + break; + + case LTC_ASN1_UTCTIME: + z = *inlen; + if (der_decode_utctime(in, &z, data) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + break; + + case LTC_ASN1_SEQUENCE: + if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { + if (der_length_sequence(data, size, &z) == CRYPT_OK) { + list[x].used = 1; + *inlen = z; + return CRYPT_OK; + } + } + break; + + default: + return CRYPT_INVALID_ARG; + } + } + + return CRYPT_INVALID_PACKET; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2005/06/19 11:25:01 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c b/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c new file mode 100644 index 0000000..ac0a4af --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c @@ -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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a IA5 STRING + @param in The DER encoded IA5 STRING + @param inlen The size of the DER IA5 STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x16 */ + if ((in[0] & 0x1F) != 0x16) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_ia5_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c b/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c new file mode 100644 index 0000000..a79b46e --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c @@ -0,0 +1,84 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an IA5 STRING + @param in The array of IA5 to store (one per char) + @param inlen The number of IA5 to store + @param out [out] The destination for the DER encoded IA5 STRING + @param outlen [in/out] The max size and resulting size of the DER IA5 STRING + @return CRYPT_OK if successful +*/ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x16; + if (inlen < 128) { + out[x++] = inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (inlen>>16)&255; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_ia5_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c b/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c new file mode 100644 index 0000000..d07d630 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c @@ -0,0 +1,194 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_ia5_string.c + ASN.1 DER, get length of IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} ia5_table[] = { +{ '\0', 0 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '#', 35 }, +{ '$', 36 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '*', 42 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ '\\', 92 }, +{ ']', 93 }, +{ '^', 94 }, +{ '_', 95 }, +{ '`', 96 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '{', 123 }, +{ '|', 124 }, +{ '}', 125 }, +{ '~', 126 } +}; + +int der_ia5_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].code == c) { + return ia5_table[x].value; + } + } + return -1; +} + +int der_ia5_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].value == v) { + return ia5_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of IA5 STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_ia5_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c b/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c new file mode 100644 index 0000000..e68b2c9 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c @@ -0,0 +1,110 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a mp_int integer + @param in The DER encoded data + @param inlen Size of DER encoded data + @param num The first mp_int to decode + @return CRYPT_OK if successful +*/ +int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num) +{ + unsigned long x, y, z; + int err; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* min DER INTEGER is 0x02 01 00 == 0 */ + if (inlen < (1 + 1 + 1)) { + return CRYPT_INVALID_PACKET; + } + + /* ok expect 0x02 when we AND with 0001 1111 [1F] */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* now decode the len stuff */ + z = in[x++]; + + if ((z & 0x80) == 0x00) { + /* short form */ + + /* will it overflow? */ + if (x + z > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, z))) != CRYPT_OK) { + return err; + } + } else { + /* long form */ + z &= 0x7F; + + /* will number of length bytes overflow? (or > 4) */ + if (((x + z) > inlen) || (z > 4) || (z == 0)) { + return CRYPT_INVALID_PACKET; + } + + /* now read it in */ + y = 0; + while (z--) { + y = ((unsigned long)(in[x++])) | (y << 8); + } + + /* now will reading y bytes overrun? */ + if ((x + y) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* no so read it */ + if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, y))) != CRYPT_OK) { + return err; + } + } + + /* see if it's negative */ + if (in[x] & 0x80) { + mp_int tmp; + if (mp_init(&tmp) != MP_OKAY) { + return CRYPT_MEM; + } + + if (mp_2expt(&tmp, mp_count_bits(num)) != MP_OKAY || mp_sub(num, &tmp, num) != MP_OKAY) { + mp_clear(&tmp); + return CRYPT_MEM; + } + mp_clear(&tmp); + } + + return CRYPT_OK; + +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2005/06/01 00:06:05 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c b/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c new file mode 100644 index 0000000..f0f41be --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c @@ -0,0 +1,128 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */ +/** + Store a mp_int integer + @param num The first mp_int to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) +{ + unsigned long tmplen, y; + int err, leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* find out how big this will be */ + if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { + return err; + } + + if (*outlen < tmplen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (mp_cmp_d(num, 0) != MP_LT) { + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ + y = mp_unsigned_bin_size(num) + leading_zero; + } else { + leading_zero = 0; + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + y = y >> 3; + + } + + /* now store initial data */ + *out++ = 0x02; + if (y < 128) { + /* short form */ + *out++ = (unsigned char)y; + } else if (y < 256) { + *out++ = 0x81; + *out++ = y; + } else if (y < 65536UL) { + *out++ = 0x82; + *out++ = (y>>8)&255; + *out++ = y; + } else if (y < 16777216UL) { + *out++ = 0x83; + *out++ = (y>>16)&255; + *out++ = (y>>8)&255; + *out++ = y; + } else { + return CRYPT_INVALID_ARG; + } + + /* now store msbyte of zero if num is non-zero */ + if (leading_zero) { + *out++ = 0x00; + } + + /* if it's not zero store it as big endian */ + if (mp_cmp_d(num, 0) == MP_GT) { + /* now store the mpint */ + if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + } else if (mp_iszero(num) != MP_YES) { + mp_int tmp; + /* negative */ + if (mp_init(&tmp) != MP_OKAY) { + return CRYPT_MEM; + } + + /* 2^roundup and subtract */ + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + if (mp_2expt(&tmp, y) != MP_OKAY || mp_add(&tmp, num, &tmp) != MP_OKAY) { + mp_clear(&tmp); + return CRYPT_MEM; + } + + if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { + mp_clear(&tmp); + return mpi_to_ltc_error(err); + } + mp_clear(&tmp); + } + + /* we good */ + *outlen = tmplen; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c b/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c new file mode 100644 index 0000000..1bfee45 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c @@ -0,0 +1,81 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The mp_int to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_integer(mp_int *num, unsigned long *outlen) +{ + unsigned long z, len; + int leading_zero; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(outlen != NULL); + + if (mp_cmp_d(num, 0) != MP_LT) { + /* positive */ + + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* size for bignum */ + z = len = leading_zero + mp_unsigned_bin_size(num); + } else { + /* it's negative */ + /* find power of 2 that is a multiple of eight and greater than count bits */ + leading_zero = 0; + z = mp_count_bits(num); + z = z + (8 - (z & 7)); + len = z = z >> 3; + } + + /* now we need a length */ + if (z < 128) { + /* short form */ + ++len; + } else { + /* long form (relies on z != 0), assumes length bytes < 128 */ + ++len; + + while (z) { + ++len; + z >>= 8; + } + } + + /* we need a 0x02 to indicate it's INTEGER */ + ++len; + + /* return length */ + *outlen = len; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c new file mode 100644 index 0000000..c69c9a3 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c @@ -0,0 +1,99 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_object_identifier.c + ASN.1 DER, Decode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Decode OID data and store the array of integers in words + @param in The OID DER encoded data + @param inlen The length of the OID data + @param words [out] The destination of the OID words + @param outlen [in/out] The number of OID words + @return CRYPT_OK if successful +*/ +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen) +{ + unsigned long x, y, t, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + /* header is at least 3 bytes */ + if (inlen < 3) { + return CRYPT_INVALID_PACKET; + } + + /* must be room for at least two words */ + if (*outlen < 2) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode the packet header */ + x = 0; + if ((in[x++] & 0x1F) != 0x06) { + return CRYPT_INVALID_PACKET; + } + + /* get the length */ + if (in[x] < 128) { + len = in[x++]; + } else { + if (in[x] < 0x81 || in[x] > 0x82) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + len = 0; + while (y--) { + len = (len << 8) | (unsigned long)in[x++]; + } + } + + if (len < 1 || (len + x) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* decode word1 and word2 */ + --len; + t = in[x++]; + words[0] = t/40; + words[1] = t%40; + + /* decode rest */ + y = 2; + t = 0; + while (len--) { + t = (t << 7) | (in[x] & 0x7F); + if (!(in[x++] & 0x80)) { + /* store t */ + if (y >= *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + words[y++] = t; + t = 0; + } + } + + *outlen = y; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c new file mode 100644 index 0000000..16eb112 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -0,0 +1,103 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_object_identifier.c + ASN.1 DER, Encode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Encode an OID + @param words The words to encode (upto 32-bits each) + @param nwords The number of words in the OID + @param out [out] Destination of OID data + @param outlen [in/out] The max and resulting size of the OID + @return CRYPT_OK if successful +*/ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, x, y, z, t, mask; + int err; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* check length */ + if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) { + return err; + } + if (x > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* compute length to store OID data */ + z = 1; + for (y = 2; y < nwords; y++) { + t = der_object_identifier_bits(words[y]); + z += t/7 + ((t%7) ? 1 : 0); + } + + /* store header + length */ + x = 0; + out[x++] = 0x06; + if (z < 128) { + out[x++] = z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (z>>8)&255; + out[x++] = z&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store first byte */ + out[x++] = words[0] * 40 + words[1]; + + for (i = 2; i < nwords; i++) { + /* store 7 bit words in little endian */ + t = words[i] & 0xFFFFFFFF; + if (t) { + y = x; + mask = 0; + while (t) { + out[x++] = (t & 0x7F) | mask; + t >>= 7; + mask |= 0x80; /* upper bit is set on all but the last byte */ + } + /* now swap bytes y...x-1 */ + z = x - 1; + while (y < z) { + t = out[y]; out[y] = out[z]; out[z] = t; + ++y; + --z; + } + } else { + /* zero word */ + out[x++] = 0x00; + } + } + + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c b/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c new file mode 100644 index 0000000..d03d1a7 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c @@ -0,0 +1,84 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_object_identifier.c + ASN.1 DER, get length of Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER + +unsigned long der_object_identifier_bits(unsigned long x) +{ + unsigned long c; + x &= 0xFFFFFFFF; + c = 0; + while (x) { + ++c; + x >>= 1; + } + return c; +} + + +/** + Gets length of DER encoding of Object Identifier + @param nwords The number of OID words + @param words The actual OID words to get the size of + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) +{ + unsigned long y, z, t; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + + /* must be >= 2 words */ + if (nwords < 2) { + return CRYPT_INVALID_ARG; + } + + /* word1 = 0,1,2 and word2 0..39 */ + if (words[0] > 2 || words[1] > 39) { + return CRYPT_INVALID_ARG; + } + + /* leading byte of first two words */ + z = 1; + for (y = 2; y < nwords; y++) { + t = der_object_identifier_bits(words[y]); + z += t/7 + ((t%7) ? 1 : 0); + } + + /* now depending on the length our length encoding changes */ + if (z < 128) { + z += 2; + } else if (z < 256) { + z += 3; + } else if (z < 65536UL) { + z += 4; + } else { + return CRYPT_INVALID_ARG; + } + + *outlen = z; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c b/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c new file mode 100644 index 0000000..2d3800f --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c @@ -0,0 +1,90 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a OCTET STRING + @param in The DER encoded OCTET STRING + @param inlen The size of the DER OCTET STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x04 */ + if ((in[0] & 0x1F) != 0x04) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + out[y] = in[x++]; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c b/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c new file mode 100644 index 0000000..f34b708 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c @@ -0,0 +1,85 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an OCTET STRING + @param in The array of OCTETS to store (one per char) + @param inlen The number of OCTETS to store + @param out [out] The destination for the DER encoded OCTET STRING + @param outlen [in/out] The max size and resulting size of the DER OCTET STRING + @return CRYPT_OK if successful +*/ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x04; + if (inlen < 128) { + out[x++] = inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (inlen>>16)&255; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = in[y]; + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c b/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c new file mode 100644 index 0000000..9a0bed3 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c @@ -0,0 +1,53 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_octet_string.c + ASN.1 DER, get length of OCTET STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of OCTET STRING + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_octet_string(unsigned long noctets, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + + if (noctets < 128) { + /* 04 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 04 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 04 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 04 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/16 15:08:11 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c b/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c new file mode 100644 index 0000000..cbc9239 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c @@ -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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a printable STRING + @param in The DER encoded printable STRING + @param inlen The size of the DER printable STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x13 */ + if ((in[0] & 0x1F) != 0x13) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_printable_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/21 02:29:54 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c b/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c new file mode 100644 index 0000000..ab4e8bf --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c @@ -0,0 +1,84 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an printable STRING + @param in The array of printable to store (one per char) + @param inlen The number of printable to store + @param out [out] The destination for the DER encoded printable STRING + @param outlen [in/out] The max size and resulting size of the DER printable STRING + @return CRYPT_OK if successful +*/ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x13; + if (inlen < 128) { + out[x++] = inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (inlen>>16)&255; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_printable_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/21 02:29:54 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c b/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c new file mode 100644 index 0000000..34065f2 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c @@ -0,0 +1,166 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_printable_string.c + ASN.1 DER, get length of Printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} printable_table[] = { +{ ' ', 32 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ '=', 61 }, +{ '?', 63 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +}; + +int der_printable_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].code == c) { + return printable_table[x].value; + } + } + return -1; +} + +int der_printable_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].value == v) { + return printable_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of Printable STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_printable_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */ +/* $Revision: 1.1 $ */ +/* $Date: 2005/05/21 02:29:54 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c new file mode 100644 index 0000000..335a882 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c @@ -0,0 +1,234 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" +#include <stdarg.h> + + +/** + @file der_decode_sequence.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE + @param in The DER encoded input + @param inlen The size of the input + @param list The list of items to decode + @param outlen The number of items in the list + @return CRYPT_OK on success +*/ +int der_decode_sequence(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen) +{ + int err, type; + unsigned long size, x, y, z, i, blksize; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* sequence type? */ + x = 0; + if (in[x++] != 0x30) { + return CRYPT_INVALID_PACKET; + } + + if (in[x] < 128) { + blksize = in[x++]; + } else if (in[x] & 0x80) { + if (in[x] < 0x81 || in[x] > 0x83) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + + /* would reading the len bytes overrun? */ + if (x + y > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read len */ + blksize = 0; + while (y--) { + blksize = (blksize << 8) | (unsigned long)in[x++]; + } + } + + /* would this blksize overflow? */ + if (x + blksize > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* ok read data */ + inlen = blksize; + for (i = 0; i < outlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + z = inlen; + if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_integer(data, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + + case LTC_ASN1_SHORT_INTEGER: + z = inlen; + if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_short_integer(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_BIT_STRING: + z = inlen; + if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_OCTET_STRING: + z = inlen; + if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_NULL: + if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + x += 2; + inlen -= 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = inlen; + if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_IA5_STRING: + z = inlen; + if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + + case LTC_ASN1_PRINTABLE_STRING: + z = inlen; + if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_UTCTIME: + z = inlen; + if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_SEQUENCE: + z = inlen; + if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + + case LTC_ASN1_CHOICE: + z = inlen; + if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c,v $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2005/06/18 19:20:23 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c new file mode 100644 index 0000000..a4a1038 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c @@ -0,0 +1,124 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" +#include <stdarg.h> + + +/** + @file der_decode_sequence_multi.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(in != NULL); + + /* get size of output that will be required */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_CHOICE: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + case LTC_ASN1_CHOICE: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_decode_sequence(in, inlen, list, x); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2005/06/18 19:20:23 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence.c b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence.c new file mode 100644 index 0000000..d53153c --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence.c @@ -0,0 +1,281 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" +#include <stdarg.h> + + +/** + @file der_encode_sequence.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_UTCTIME: + if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* too big ? */ + if (*outlen < y) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* store header */ + x = 0; + out[x++] = 0x30; + if (z < 128) { + out[x++] = z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (z>>8UL)&255; + out[x++] = z&255; + } else if (z < 16777216UL) { + out[x++] = 0x83; + out[x++] = (z>>16UL)&255; + out[x++] = (z>>8UL)&255; + out[x++] = z&255; + } + + /* store data */ + *outlen -= x; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + z = *outlen; + if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SHORT_INTEGER: + z = *outlen; + if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_BIT_STRING: + z = *outlen; + if ((err = der_encode_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) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_NULL: + out[x++] = 0x05; + out[x++] = 0x00; + *outlen -= 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = *outlen; + if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_IA5_STRING: + z = *outlen; + if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_PRINTABLE_STRING: + z = *outlen; + if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_UTCTIME: + z = *outlen; + if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SEQUENCE: + z = *outlen; + if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + *outlen = x; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c new file mode 100644 index 0000000..9ff48b9 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c @@ -0,0 +1,123 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" +#include <stdarg.h> + + +/** + @file der_encode_sequence_multi.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_UTCTIME: + case LTC_ASN1_SEQUENCE: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_encode_sequence(list, x, out, outlen); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2005/06/18 19:20:23 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c b/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c new file mode 100644 index 0000000..9120451 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c @@ -0,0 +1,144 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" +#include <stdarg.h> + + +/** + @file der_length_sequence.c + ASN.1 DER, length a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Get the length of a DER sequence + @param list The sequences of items in the SEQUENCE + @param inlen The number of items + @param outlen [out] The length required in octets to store it + @return CRYPT_OK on success +*/ +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* store size */ + *outlen = y; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif diff --git a/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c b/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c new file mode 100644 index 0000000..7d3d3b7 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c @@ -0,0 +1,68 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_short_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a mp_int integer + @param in The DER encoded data + @param inlen Size of data + @param num [out] The integer to decode + @return CRYPT_OK if successful +*/ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num) +{ + unsigned long len, x, y; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* check length */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check header */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* get the packet len */ + len = in[x++]; + + if (x + len > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read number */ + y = 0; + while (len--) { + y = (y<<8) | (unsigned long)in[x++]; + } + *num = y; + + return CRYPT_OK; + +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2005/05/23 01:04:13 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c b/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c new file mode 100644 index 0000000..eb94d38 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_short_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/* Exports a positive integer as DER format (upto 32-bits in size) */ +/** + Store a mp_int integer + @param num The integer to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y, z; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* find out how big this will be */ + if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) { + return err; + } + + if (*outlen < len) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* get len of output */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* see if msb is set */ + z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* adjust the number so the msB is non-zero */ + for (x = 0; (z <= 4) && (x < (4 - z)); x++) { + num <<= 8; + } + + /* store header */ + x = 0; + out[x++] = 0x02; + out[x++] = z; + + /* if 31st bit is set output a leading zero and decrement count */ + if (z == 5) { + out[x++] = 0; + --z; + } + + /* store values */ + for (y = 0; y < z; y++) { + out[x++] = (num >> 24) & 0xFF; + num <<= 8; + } + + /* we good */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2005/05/23 01:27:03 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c b/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c new file mode 100644 index 0000000..7324b4a --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.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. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_short_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The integer to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_short_integer(unsigned long num, unsigned long *outlen) +{ + unsigned long z, y, len; + + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* get the number of bytes */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* we need a 0x02 to indicate it's INTEGER */ + len = 1; + + /* length byte */ + ++len; + + /* bytes in value */ + len += z; + + /* see if msb is set */ + len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* return length */ + *outlen = len; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */ +/* $Revision: 1.3 $ */ +/* $Date: 2005/05/23 01:35:38 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c b/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c new file mode 100644 index 0000000..43ba033 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c @@ -0,0 +1,120 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_utctime.c + ASN.1 DER, decode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static int char_to_int(unsigned char x) +{ + switch (x) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + } + return 100; +} + +#define DECODE_V(y, max) \ + y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ + if (y >= max) return CRYPT_INVALID_PACKET; \ + x += 2; + +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out) +{ + unsigned char buf[32]; + unsigned long x; + int y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != NULL); + LTC_ARGCHK(out != NULL); + + /* check header */ + if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* decode the string */ + for (x = 0; x < in[1]; x++) { + y = der_ia5_value_decode(in[x+2]); + if (y == -1) { + return CRYPT_INVALID_PACKET; + } + buf[x] = y; + } + *inlen = 2 + x; + + + /* possible encodings are +YYMMDDhhmmZ +YYMMDDhhmm+hh'mm' +YYMMDDhhmm-hh'mm' +YYMMDDhhmmssZ +YYMMDDhhmmss+hh'mm' +YYMMDDhhmmss-hh'mm' + + So let's do a trivial decode upto [including] mm + */ + + x = 0; + DECODE_V(out->YY, 100); + DECODE_V(out->MM, 13); + DECODE_V(out->DD, 32); + DECODE_V(out->hh, 24); + DECODE_V(out->mm, 60); + + /* clear timezone and seconds info */ + out->off_dir = out->off_hh = out->off_mm = out->ss = 0; + + /* now is it Z, +, - or 0-9 */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } + + /* decode seconds */ + DECODE_V(out->ss, 60); + + /* now is it Z, +, - */ + if (buf[x] == 'Z') { + return CRYPT_OK; + } else if (buf[x] == '+' || buf[x] == '-') { + out->off_dir = (buf[x++] == '+') ? 0 : 1; + DECODE_V(out->off_hh, 24); + DECODE_V(out->off_mm, 60); + return CRYPT_OK; + } else { + return CRYPT_INVALID_PACKET; + } +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */ +/* $Revision: 1.6 $ */ +/* $Date: 2005/06/19 12:07:00 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c b/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c new file mode 100644 index 0000000..dad8c84 --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c @@ -0,0 +1,80 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_utctime.c + ASN.1 DER, encode a UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +static const char *baseten = "0123456789"; + +#define STORE_V(y) \ + out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ + out[x++] = der_ia5_char_encode(baseten[y % 10]); + +/** + Gets length of DER encoding of UTCTIME + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, tmplen; + int err; + + LTC_ARGCHK(utctime != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) { + return err; + } + if (tmplen > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + out[0] = 0x17; + + /* store values */ + x = 2; + STORE_V(utctime->YY); + STORE_V(utctime->MM); + STORE_V(utctime->DD); + STORE_V(utctime->hh); + STORE_V(utctime->mm); + STORE_V(utctime->ss); + + if (utctime->off_mm || utctime->off_hh) { + out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+'); + STORE_V(utctime->off_hh); + STORE_V(utctime->off_mm); + } else { + out[x++] = der_ia5_char_encode('Z'); + } + + /* store length */ + out[1] = x - 2; + + /* all good let's return */ + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c,v $ */ +/* $Revision: 1.5 $ */ +/* $Date: 2005/06/19 12:07:00 $ */ diff --git a/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c b/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c new file mode 100644 index 0000000..84e654a --- /dev/null +++ b/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c @@ -0,0 +1,45 @@ +/* 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://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_utctime.c + ASN.1 DER, get length of UTCTIME, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Gets length of DER encoding of UTCTIME + @param outlen [out] The length of the DER encoding + @return CRYPT_OK if successful +*/ +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(utctime != NULL); + + if (utctime->off_hh == 0 && utctime->off_mm == 0) { + /* we encode as YYMMDDhhmmssZ */ + *outlen = 2 + 13; + } else { + /* we encode as YYMMDDhhmmss{+|-}hh'mm' */ + *outlen = 2 + 17; + } + + return CRYPT_OK; +} + +#endif + +/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */ +/* $Revision: 1.2 $ */ +/* $Date: 2005/06/19 11:23:04 $ */ |