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_encode_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 an UTF8 STRING 23 @param in The array of UTF8 to store (one per wchar_t) 24 @param inlen The number of UTF8 to store 25 @param out [out] The destination for the DER encoded UTF8 STRING 26 @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING 27 @return CRYPT_OK if successful 28 */ 29 int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, 30 unsigned char *out, unsigned long *outlen) 31 { 32 unsigned long x, y, len; 33 34 LTC_ARGCHK(in != NULL); 35 LTC_ARGCHK(out != NULL); 36 LTC_ARGCHK(outlen != NULL); 37 38 /* get the size */ 39 for (x = len = 0; x < inlen; x++) { 40 if (in[x] < 0 || in[x] > 0x1FFFF) { 41 return CRYPT_INVALID_ARG; 42 } 43 len += der_utf8_charsize(in[x]); 44 } 45 46 if (len < 128) { 47 y = 2 + len; 48 } else if (len < 256) { 49 y = 3 + len; 50 } else if (len < 65536UL) { 51 y = 4 + len; 52 } else if (len < 16777216UL) { 53 y = 5 + len; 54 } else { 55 return CRYPT_INVALID_ARG; 56 } 57 58 /* too big? */ 59 if (y > *outlen) { 60 *outlen = len; 61 return CRYPT_BUFFER_OVERFLOW; 62 } 63 64 /* encode the header+len */ 65 x = 0; 66 out[x++] = 0x0C; 67 if (len < 128) { 68 out[x++] = len; 69 } else if (len < 256) { 70 out[x++] = 0x81; 71 out[x++] = len; 72 } else if (len < 65536UL) { 73 out[x++] = 0x82; 74 out[x++] = (len>>8)&255; 75 out[x++] = len&255; 76 } else if (len < 16777216UL) { 77 out[x++] = 0x83; 78 out[x++] = (len>>16)&255; 79 out[x++] = (len>>8)&255; 80 out[x++] = len&255; 81 } else { 82 return CRYPT_INVALID_ARG; 83 } 84 85 /* store UTF8 */ 86 for (y = 0; y < inlen; y++) { 87 switch (der_utf8_charsize(in[y])) { 88 case 1: out[x++] = in[y]; break; 89 case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break; 90 case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; 91 case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; 92 } 93 } 94 95 /* retun length */ 96 *outlen = x; 97 98 return CRYPT_OK; 99 } 100 101 #endif 102 103 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c,v $ */ 104 /* $Revision: 1.7 $ */ 105 /* $Date: 2006/12/16 17:41:21 $ */ 106