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