]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / 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 #include "tomcrypt.h"
10
11 /**
12   @file der_encode_utf8_string.c
13   ASN.1 DER, encode a UTF8 STRING, Tom St Denis
14 */
15
16
17 #ifdef LTC_DER
18
19 /**
20   Store an UTF8 STRING
21   @param in       The array of UTF8 to store (one per wchar_t)
22   @param inlen    The number of UTF8 to store
23   @param out      [out] The destination for the DER encoded UTF8 STRING
24   @param outlen   [in/out] The max size and resulting size of the DER UTF8 STRING
25   @return CRYPT_OK if successful
26 */
27 int der_encode_utf8_string(const wchar_t *in,  unsigned long inlen,
28                            unsigned char *out, unsigned long *outlen)
29 {
30    unsigned long x, y, len;
31
32    LTC_ARGCHK(in     != NULL);
33    LTC_ARGCHK(out    != NULL);
34    LTC_ARGCHK(outlen != NULL);
35
36    /* get the size */
37    for (x = len = 0; x < inlen; x++) {
38        if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG;
39        len += der_utf8_charsize(in[x]);
40    }
41
42    if (len < 128) {
43       y = 2 + len;
44    } else if (len < 256) {
45       y = 3 + len;
46    } else if (len < 65536UL) {
47       y = 4 + len;
48    } else if (len < 16777216UL) {
49       y = 5 + len;
50    } else {
51       return CRYPT_INVALID_ARG;
52    }
53
54    /* too big? */
55    if (y > *outlen) {
56       *outlen = y;
57       return CRYPT_BUFFER_OVERFLOW;
58    }
59
60    /* encode the header+len */
61    x = 0;
62    out[x++] = 0x0C;
63    if (len < 128) {
64       out[x++] = (unsigned char)len;
65    } else if (len < 256) {
66       out[x++] = 0x81;
67       out[x++] = (unsigned char)len;
68    } else if (len < 65536UL) {
69       out[x++] = 0x82;
70       out[x++] = (unsigned char)((len>>8)&255);
71       out[x++] = (unsigned char)(len&255);
72    } else if (len < 16777216UL) {
73       out[x++] = 0x83;
74       out[x++] = (unsigned char)((len>>16)&255);
75       out[x++] = (unsigned char)((len>>8)&255);
76       out[x++] = (unsigned char)(len&255);
77    } else {
78        /* coverity[dead_error_line] */
79       return CRYPT_INVALID_ARG;
80    }
81
82    /* store UTF8 */
83    for (y = 0; y < inlen; y++) {
84        switch (der_utf8_charsize(in[y])) {
85           case 1: out[x++] = (unsigned char)in[y]; break;
86           case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F);  out[x++] = 0x80 | (in[y] & 0x3F); break;
87           case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
88 #if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF
89           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;
90 #endif
91        }
92    }
93
94    /* retun length */
95    *outlen = x;
96
97    return CRYPT_OK;
98 }
99
100 #endif
101
102 /* ref:         $Format:%D$ */
103 /* git commit:  $Format:%H$ */
104 /* commit time: $Format:%ai$ */