1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file der_decode_ia5_string.c
7   ASN.1 DER, encode a IA5 STRING, Tom St Denis
8 */
9 
10 
11 #ifdef LTC_DER
12 
13 /**
14   Store a IA5 STRING
15   @param in      The DER encoded IA5 STRING
16   @param inlen   The size of the DER IA5 STRING
17   @param out     [out] The array of octets stored (one per char)
18   @param outlen  [in/out] The number of octets stored
19   @return CRYPT_OK if successful
20 */
der_decode_ia5_string(const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned long * outlen)21 int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
22                                 unsigned char *out, unsigned long *outlen)
23 {
24    unsigned long x, y, len;
25    int           t, err;
26 
27    LTC_ARGCHK(in     != NULL);
28    LTC_ARGCHK(out    != NULL);
29    LTC_ARGCHK(outlen != NULL);
30 
31    /* must have header at least */
32    if (inlen < 2) {
33       return CRYPT_INVALID_PACKET;
34    }
35 
36    /* check for 0x16 */
37    if ((in[0] & 0x1F) != 0x16) {
38       return CRYPT_INVALID_PACKET;
39    }
40    x = 1;
41 
42    /* get the length of the data */
43    y = inlen - x;
44    if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
45       return err;
46    }
47    x += y;
48 
49    /* is it too long? */
50    if (len > *outlen) {
51       *outlen = len;
52       return CRYPT_BUFFER_OVERFLOW;
53    }
54 
55    if (len > (inlen - x)) {
56       return CRYPT_INVALID_PACKET;
57    }
58 
59    /* read the data */
60    for (y = 0; y < len; y++) {
61        t = der_ia5_value_decode(in[x++]);
62        if (t == -1) {
63            return CRYPT_INVALID_ARG;
64        }
65        out[y] = t;
66    }
67 
68    *outlen = y;
69 
70    return CRYPT_OK;
71 }
72 
73 #endif
74