]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / asn1 / der / utf8 / der_decode_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_decode_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 a UTF8 STRING
21   @param in      The DER encoded UTF8 STRING
22   @param inlen   The size of the DER UTF8 STRING
23   @param out     [out] The array of utf8s stored (one per char)
24   @param outlen  [in/out] The number of utf8s stored
25   @return CRYPT_OK if successful
26 */
27 int der_decode_utf8_string(const unsigned char *in,  unsigned long inlen,
28                                        wchar_t *out, unsigned long *outlen)
29 {
30    wchar_t       tmp;
31    unsigned long x, y, z, len;
32    int err;
33
34    LTC_ARGCHK(in     != NULL);
35    LTC_ARGCHK(out    != NULL);
36    LTC_ARGCHK(outlen != NULL);
37
38    /* must have header at least */
39    if (inlen < 2) {
40       return CRYPT_INVALID_PACKET;
41    }
42
43    /* check for 0x0C */
44    if ((in[0] & 0x1F) != 0x0C) {
45       return CRYPT_INVALID_PACKET;
46    }
47    x = 1;
48
49    /* decode the length */
50    if (in[x] & 0x80) {
51       /* valid # of bytes in length are 1,2,3 */
52       y = in[x] & 0x7F;
53       if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
54          return CRYPT_INVALID_PACKET;
55       }
56
57       /* read the length in */
58       len = 0;
59       ++x;
60       while (y--) {
61          len = (len << 8) | in[x++];
62       }
63    } else {
64       len = in[x++] & 0x7F;
65    }
66
67    if (len + x > inlen) {
68       return CRYPT_INVALID_PACKET;
69    }
70
71    /* proceed to decode */
72    for (y = 0; x < inlen; ) {
73       /* get first byte */
74       tmp = in[x++];
75
76       /* count number of bytes */
77       for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF);
78
79       if (z > 4 || (x + (z - 1) > inlen)) {
80          return CRYPT_INVALID_PACKET;
81       }
82
83       /* decode, grab upper bits */
84       tmp >>= z;
85
86       /* grab remaining bytes */
87       if (z > 1) { --z; }
88       while (z-- != 0) {
89          if ((in[x] & 0xC0) != 0x80) {
90             return CRYPT_INVALID_PACKET;
91          }
92          tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F);
93       }
94
95       if (y < *outlen) {
96          out[y] = tmp;
97       }
98       y++;
99    }
100    if (y > *outlen) {
101       err = CRYPT_BUFFER_OVERFLOW;
102    } else {
103       err = CRYPT_OK;
104    }
105    *outlen = y;
106
107    return err;
108 }
109
110 #endif
111
112 /* ref:         $Format:%D$ */
113 /* git commit:  $Format:%H$ */
114 /* commit time: $Format:%ai$ */