1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file der_decode_octet_string.c
7   ASN.1 DER, encode a OCTET STRING, Tom St Denis
8 */
9 
10 
11 #ifdef LTC_DER
12 
13 /**
14   Store a OCTET STRING
15   @param in      The DER encoded OCTET STRING
16   @param inlen   The size of the DER OCTET 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_octet_string(const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned long * outlen)21 int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
22                                   unsigned char *out, unsigned long *outlen)
23 {
24    unsigned long x, y, len;
25    int 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 0x04 */
37    if ((in[0] & 0x1F) != 0x04) {
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        out[y] = in[x++];
62    }
63 
64    *outlen = y;
65 
66    return CRYPT_OK;
67 }
68 
69 #endif
70