version 0.3.33
[fms.git] / libs / libtomcrypt / pk / asn1 / der / utf8 / der_encode_utf8_string.c
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@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 $ */