1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file der_decode_object_identifier.c
7 ASN.1 DER, Decode Object Identifier, Tom St Denis
8 */
9
10 #ifdef LTC_DER
11 /**
12 Decode OID data and store the array of integers in words
13 @param in The OID DER encoded data
14 @param inlen The length of the OID data
15 @param words [out] The destination of the OID words
16 @param outlen [in/out] The number of OID words
17 @return CRYPT_OK if successful
18 */
der_decode_object_identifier(const unsigned char * in,unsigned long inlen,unsigned long * words,unsigned long * outlen)19 int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
20 unsigned long *words, unsigned long *outlen)
21 {
22 unsigned long x, y, t, len;
23 int err;
24
25 LTC_ARGCHK(in != NULL);
26 LTC_ARGCHK(words != NULL);
27 LTC_ARGCHK(outlen != NULL);
28
29 /* header is at least 3 bytes */
30 if (inlen < 3) {
31 return CRYPT_INVALID_PACKET;
32 }
33
34 /* must be room for at least two words */
35 if (*outlen < 2) {
36 *outlen = 2;
37 return CRYPT_BUFFER_OVERFLOW;
38 }
39
40 /* decode the packet header */
41 x = 0;
42 if ((in[x++] & 0x1F) != 0x06) {
43 return CRYPT_INVALID_PACKET;
44 }
45
46 /* get the length of the data */
47 y = inlen - x;
48 if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
49 return err;
50 }
51 x += y;
52
53 if ((len == 0) || (len > (inlen - x))) {
54 return CRYPT_INVALID_PACKET;
55 }
56
57 /* decode words */
58 y = 0;
59 t = 0;
60 while (len--) {
61 t = (t << 7) | (in[x] & 0x7F);
62 if (!(in[x++] & 0x80)) {
63 /* store t */
64 if (y >= *outlen) {
65 y++;
66 } else {
67 if (y == 0) {
68 if (t <= 79) {
69 words[0] = t / 40;
70 words[1] = t % 40;
71 } else {
72 words[0] = 2;
73 words[1] = t - 80;
74 }
75 y = 2;
76 } else {
77 words[y++] = t;
78 }
79 }
80 t = 0;
81 }
82 }
83
84 if (y > *outlen) {
85 err = CRYPT_BUFFER_OVERFLOW;
86 } else {
87 err = CRYPT_OK;
88 }
89
90 *outlen = y;
91 return err;
92 }
93
94 #endif
95