1 // SPDX-License-Identifier: BSD-2-Clause 2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis 3 * 4 * LibTomCrypt is a library that provides various cryptographic 5 * algorithms in a highly modular and flexible manner. 6 * 7 * The library is free for all purposes without any express 8 * guarantee it works. 9 */ 10 #include "tomcrypt_private.h" 11 12 /** 13 @file der_encode_asn1_identifier.c 14 ASN.1 DER, encode the ASN.1 Identifier, Steffen Jaeckel 15 */ 16 17 #ifdef LTC_DER 18 /** 19 Encode the ASN.1 Identifier 20 @param id The ASN.1 Identifer to encode 21 @param out Where to write the identifier to 22 @param outlen [in/out] The size of out available/written 23 @return CRYPT_OK if successful 24 */ der_encode_asn1_identifier(const ltc_asn1_list * id,unsigned char * out,unsigned long * outlen)25int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen) 26 { 27 ulong64 tmp; 28 unsigned long tag_len; 29 30 LTC_ARGCHK(id != NULL); 31 LTC_ARGCHK(outlen != NULL); 32 33 if (id->type != LTC_ASN1_CUSTOM_TYPE) { 34 if ((unsigned)id->type >= der_asn1_type_to_identifier_map_sz) { 35 return CRYPT_INVALID_ARG; 36 } 37 if (der_asn1_type_to_identifier_map[id->type] == -1) { 38 return CRYPT_INVALID_ARG; 39 } 40 if (out != NULL) { 41 *out = der_asn1_type_to_identifier_map[id->type]; 42 } 43 *outlen = 1; 44 return CRYPT_OK; 45 } 46 if (id->klass < LTC_ASN1_CL_UNIVERSAL || id->klass > LTC_ASN1_CL_PRIVATE) { 47 return CRYPT_INVALID_ARG; 48 } 49 if (id->pc < LTC_ASN1_PC_PRIMITIVE || id->pc > LTC_ASN1_PC_CONSTRUCTED) { 50 return CRYPT_INVALID_ARG; 51 } 52 if (id->tag > (ULONG_MAX >> (8 + 7))) { 53 return CRYPT_INVALID_ARG; 54 } 55 56 if (out != NULL) { 57 if (*outlen < 1) { 58 return CRYPT_BUFFER_OVERFLOW; 59 } 60 61 out[0] = id->klass << 6 | id->pc << 5; 62 } 63 64 if (id->tag < 0x1f) { 65 if (out != NULL) { 66 out[0] |= id->tag & 0x1f; 67 } 68 *outlen = 1; 69 } else { 70 tag_len = 0; 71 tmp = id->tag; 72 do { 73 tag_len++; 74 tmp >>= 7; 75 } while (tmp); 76 77 if (out != NULL) { 78 if (*outlen < tag_len + 1) { 79 return CRYPT_BUFFER_OVERFLOW; 80 } 81 out[0] |= 0x1f; 82 for (tmp = 1; tmp <= tag_len; ++tmp) { 83 out[tmp] = ((id->tag >> (7 * (tag_len - tmp))) & 0x7f) | 0x80; 84 } 85 out[tag_len] &= ~0x80; 86 } 87 *outlen = tag_len + 1; 88 } 89 90 return CRYPT_OK; 91 } 92 93 #endif 94 95 /* ref: $Format:%D$ */ 96 /* git commit: $Format:%H$ */ 97 /* commit time: $Format:%ai$ */ 98