1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis 2 * 3 * LibTomCrypt is a library that provides various cryptographic 4 * algorithms in a highly modular and flexible manner. 5 * 6 * The library is free for all purposes without any express 7 * guarantee it works. 8 * 9 * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com 10 */ 11 #include "tomcrypt.h" 12 13 /** 14 @file der_decode_utf8_string.c 15 ASN.1 DER, encode a UTF8 STRING, Tom St Denis 16 */ 17 18 19 #ifdef LTC_DER 20 21 /** 22 Store a UTF8 STRING 23 @param in The DER encoded UTF8 STRING 24 @param inlen The size of the DER UTF8 STRING 25 @param out [out] The array of utf8s stored (one per char) 26 @param outlen [in/out] The number of utf8s stored 27 @return CRYPT_OK if successful 28 */ 29 int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, 30 wchar_t *out, unsigned long *outlen) 31 { 32 wchar_t tmp; 33 unsigned long x, y, z, len; 34 35 LTC_ARGCHK(in != NULL); 36 LTC_ARGCHK(out != NULL); 37 LTC_ARGCHK(outlen != NULL); 38 39 /* must have header at least */ 40 if (inlen < 2) { 41 return CRYPT_INVALID_PACKET; 42 } 43 44 /* check for 0x0C */ 45 if ((in[0] & 0x1F) != 0x0C) { 46 return CRYPT_INVALID_PACKET; 47 } 48 x = 1; 49 50 /* decode the length */ 51 if (in[x] & 0x80) { 52 /* valid # of bytes in length are 1,2,3 */ 53 y = in[x] & 0x7F; 54 if ((y == 0) || (y > 3) || ((x + y) > inlen)) { 55 return CRYPT_INVALID_PACKET; 56 } 57 58 /* read the length in */ 59 len = 0; 60 ++x; 61 while (y--) { 62 len = (len << 8) | in[x++]; 63 } 64 } else { 65 len = in[x++] & 0x7F; 66 } 67 68 if (len + x > inlen) { 69 return CRYPT_INVALID_PACKET; 70 } 71 72 /* proceed to decode */ 73 for (y = 0; x < inlen; ) { 74 /* get first byte */ 75 tmp = in[x++]; 76 77 /* count number of bytes */ 78 for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); 79 80 if (z > 4 || (x + (z - 1) > inlen)) { 81 return CRYPT_INVALID_PACKET; 82 } 83 84 /* decode, grab upper bits */ 85 tmp >>= z; 86 87 /* grab remaining bytes */ 88 if (z > 1) { --z; } 89 while (z-- != 0) { 90 if ((in[x] & 0xC0) != 0x80) { 91 return CRYPT_INVALID_PACKET; 92 } 93 tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); 94 } 95 96 if (y > *outlen) { 97 *outlen = y; 98 return CRYPT_BUFFER_OVERFLOW; 99 } 100 out[y++] = tmp; 101 } 102 *outlen = y; 103 104 return CRYPT_OK; 105 } 106 107 #endif 108 109 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c,v $ */ 110 /* $Revision: 1.7 $ */ 111 /* $Date: 2006/11/26 02:27:37 $ */ 112