199d423f1SLei He /* 299d423f1SLei He * QEMU Crypto ASN.1 DER decoder 399d423f1SLei He * 499d423f1SLei He * Copyright (c) 2022 Bytedance 599d423f1SLei He * Author: lei he <helei.sig11@bytedance.com> 699d423f1SLei He * 799d423f1SLei He * This library is free software; you can redistribute it and/or 899d423f1SLei He * modify it under the terms of the GNU Lesser General Public 999d423f1SLei He * License as published by the Free Software Foundation; either 1099d423f1SLei He * version 2.1 of the License, or (at your option) any later version. 1199d423f1SLei He * 1299d423f1SLei He * This library is distributed in the hope that it will be useful, 1399d423f1SLei He * but WITHOUT ANY WARRANTY; without even the implied warranty of 1499d423f1SLei He * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1599d423f1SLei He * Lesser General Public License for more details. 1699d423f1SLei He * 1799d423f1SLei He * You should have received a copy of the GNU Lesser General Public 1899d423f1SLei He * License along with this library; if not, see <http://www.gnu.org/licenses/>. 1999d423f1SLei He * 2099d423f1SLei He */ 2199d423f1SLei He 2299d423f1SLei He #include "qemu/osdep.h" 2399d423f1SLei He #include "crypto/der.h" 2499d423f1SLei He 25*3b34ccadSLei He typedef struct QCryptoDerEncodeNode { 26*3b34ccadSLei He uint8_t tag; 27*3b34ccadSLei He struct QCryptoDerEncodeNode *parent; 28*3b34ccadSLei He struct QCryptoDerEncodeNode *next; 29*3b34ccadSLei He /* for constructed type, data is null */ 30*3b34ccadSLei He const uint8_t *data; 31*3b34ccadSLei He size_t dlen; 32*3b34ccadSLei He } QCryptoDerEncodeNode; 33*3b34ccadSLei He 34*3b34ccadSLei He typedef struct QCryptoEncodeContext { 35*3b34ccadSLei He QCryptoDerEncodeNode root; 36*3b34ccadSLei He QCryptoDerEncodeNode *current_parent; 37*3b34ccadSLei He QCryptoDerEncodeNode *tail; 38*3b34ccadSLei He } QCryptoEncodeContext; 39*3b34ccadSLei He 4099d423f1SLei He enum QCryptoDERTypeTag { 4199d423f1SLei He QCRYPTO_DER_TYPE_TAG_BOOL = 0x1, 4299d423f1SLei He QCRYPTO_DER_TYPE_TAG_INT = 0x2, 4399d423f1SLei He QCRYPTO_DER_TYPE_TAG_BIT_STR = 0x3, 4499d423f1SLei He QCRYPTO_DER_TYPE_TAG_OCT_STR = 0x4, 45*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_NULL = 0x5, 46*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_OID = 0x6, 4799d423f1SLei He QCRYPTO_DER_TYPE_TAG_SEQ = 0x10, 4899d423f1SLei He QCRYPTO_DER_TYPE_TAG_SET = 0x11, 4999d423f1SLei He }; 5099d423f1SLei He 51*3b34ccadSLei He enum QCryptoDERTagClass { 52*3b34ccadSLei He QCRYPTO_DER_TAG_CLASS_UNIV = 0x0, 53*3b34ccadSLei He QCRYPTO_DER_TAG_CLASS_APPL = 0x1, 54*3b34ccadSLei He QCRYPTO_DER_TAG_CLASS_CONT = 0x2, 55*3b34ccadSLei He QCRYPTO_DER_TAG_CLASS_PRIV = 0x3, 56*3b34ccadSLei He }; 57*3b34ccadSLei He 58*3b34ccadSLei He enum QCryptoDERTagEnc { 59*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM = 0x0, 60*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_CONS = 0x1, 61*3b34ccadSLei He }; 62*3b34ccadSLei He 63*3b34ccadSLei He #define QCRYPTO_DER_TAG_ENC_MASK 0x20 64*3b34ccadSLei He #define QCRYPTO_DER_TAG_ENC_SHIFT 5 65*3b34ccadSLei He 66*3b34ccadSLei He #define QCRYPTO_DER_TAG_CLASS_MASK 0xc0 67*3b34ccadSLei He #define QCRYPTO_DER_TAG_CLASS_SHIFT 6 68*3b34ccadSLei He 69*3b34ccadSLei He #define QCRYPTO_DER_TAG_VAL_MASK 0x1f 7099d423f1SLei He #define QCRYPTO_DER_SHORT_LEN_MASK 0x80 7199d423f1SLei He 72*3b34ccadSLei He #define QCRYPTO_DER_TAG(class, enc, val) \ 73*3b34ccadSLei He (((class) << QCRYPTO_DER_TAG_CLASS_SHIFT) | \ 74*3b34ccadSLei He ((enc) << QCRYPTO_DER_TAG_ENC_SHIFT) | (val)) 75*3b34ccadSLei He 76*3b34ccadSLei He /** 77*3b34ccadSLei He * qcrypto_der_encode_length: 78*3b34ccadSLei He * @src_len: the length of source data 79*3b34ccadSLei He * @dst: distination to save the encoded 'length', if dst is NULL, only compute 80*3b34ccadSLei He * the expected buffer size in bytes. 81*3b34ccadSLei He * @dst_len: output parameter, indicates how many bytes wrote. 82*3b34ccadSLei He * 83*3b34ccadSLei He * Encode the 'length' part of TLV tuple. 84*3b34ccadSLei He */ 85*3b34ccadSLei He static void qcrypto_der_encode_length(size_t src_len, 86*3b34ccadSLei He uint8_t *dst, size_t *dst_len) 87*3b34ccadSLei He { 88*3b34ccadSLei He size_t max_length = 0xFF; 89*3b34ccadSLei He uint8_t length_bytes = 0, header_byte; 90*3b34ccadSLei He 91*3b34ccadSLei He if (src_len < QCRYPTO_DER_SHORT_LEN_MASK) { 92*3b34ccadSLei He header_byte = src_len; 93*3b34ccadSLei He *dst_len = 1; 94*3b34ccadSLei He } else { 95*3b34ccadSLei He for (length_bytes = 1; max_length < src_len; length_bytes++) { 96*3b34ccadSLei He max_length = (max_length << 8) + max_length; 97*3b34ccadSLei He } 98*3b34ccadSLei He header_byte = length_bytes; 99*3b34ccadSLei He header_byte |= QCRYPTO_DER_SHORT_LEN_MASK; 100*3b34ccadSLei He *dst_len = length_bytes + 1; 101*3b34ccadSLei He } 102*3b34ccadSLei He if (!dst) { 103*3b34ccadSLei He return; 104*3b34ccadSLei He } 105*3b34ccadSLei He *dst++ = header_byte; 106*3b34ccadSLei He /* Bigendian length bytes */ 107*3b34ccadSLei He for (; length_bytes > 0; length_bytes--) { 108*3b34ccadSLei He *dst++ = ((src_len >> (length_bytes - 1) * 8) & 0xFF); 109*3b34ccadSLei He } 110*3b34ccadSLei He } 111*3b34ccadSLei He 11299d423f1SLei He static uint8_t qcrypto_der_peek_byte(const uint8_t **data, size_t *dlen) 11399d423f1SLei He { 11499d423f1SLei He return **data; 11599d423f1SLei He } 11699d423f1SLei He 11799d423f1SLei He static void qcrypto_der_cut_nbytes(const uint8_t **data, 11899d423f1SLei He size_t *dlen, 11999d423f1SLei He size_t nbytes) 12099d423f1SLei He { 12199d423f1SLei He *data += nbytes; 12299d423f1SLei He *dlen -= nbytes; 12399d423f1SLei He } 12499d423f1SLei He 12599d423f1SLei He static uint8_t qcrypto_der_cut_byte(const uint8_t **data, size_t *dlen) 12699d423f1SLei He { 12799d423f1SLei He uint8_t val = qcrypto_der_peek_byte(data, dlen); 12899d423f1SLei He 12999d423f1SLei He qcrypto_der_cut_nbytes(data, dlen, 1); 13099d423f1SLei He 13199d423f1SLei He return val; 13299d423f1SLei He } 13399d423f1SLei He 13499d423f1SLei He static int qcrypto_der_invoke_callback(QCryptoDERDecodeCb cb, void *ctx, 13599d423f1SLei He const uint8_t *value, size_t vlen, 13699d423f1SLei He Error **errp) 13799d423f1SLei He { 13899d423f1SLei He if (!cb) { 13999d423f1SLei He return 0; 14099d423f1SLei He } 14199d423f1SLei He 14299d423f1SLei He return cb(ctx, value, vlen, errp); 14399d423f1SLei He } 14499d423f1SLei He 14599d423f1SLei He static int qcrypto_der_extract_definite_data(const uint8_t **data, size_t *dlen, 14699d423f1SLei He QCryptoDERDecodeCb cb, void *ctx, 14799d423f1SLei He Error **errp) 14899d423f1SLei He { 14999d423f1SLei He const uint8_t *value; 15099d423f1SLei He size_t vlen = 0; 15199d423f1SLei He uint8_t byte_count = qcrypto_der_cut_byte(data, dlen); 15299d423f1SLei He 15399d423f1SLei He /* short format of definite-length */ 15499d423f1SLei He if (!(byte_count & QCRYPTO_DER_SHORT_LEN_MASK)) { 15599d423f1SLei He if (byte_count > *dlen) { 15699d423f1SLei He error_setg(errp, "Invalid content length: %u", byte_count); 15799d423f1SLei He return -1; 15899d423f1SLei He } 15999d423f1SLei He 16099d423f1SLei He value = *data; 16199d423f1SLei He vlen = byte_count; 16299d423f1SLei He qcrypto_der_cut_nbytes(data, dlen, vlen); 16399d423f1SLei He 16499d423f1SLei He if (qcrypto_der_invoke_callback(cb, ctx, value, vlen, errp) != 0) { 16599d423f1SLei He return -1; 16699d423f1SLei He } 16799d423f1SLei He return vlen; 16899d423f1SLei He } 16999d423f1SLei He 17099d423f1SLei He /* Ignore highest bit */ 17199d423f1SLei He byte_count &= ~QCRYPTO_DER_SHORT_LEN_MASK; 17299d423f1SLei He 17399d423f1SLei He /* 17499d423f1SLei He * size_t is enough to store the value of length, although the DER 17599d423f1SLei He * encoding standard supports larger length. 17699d423f1SLei He */ 17799d423f1SLei He if (byte_count > sizeof(size_t)) { 17899d423f1SLei He error_setg(errp, "Invalid byte count of content length: %u", 17999d423f1SLei He byte_count); 18099d423f1SLei He return -1; 18199d423f1SLei He } 18299d423f1SLei He 18399d423f1SLei He if (byte_count > *dlen) { 18499d423f1SLei He error_setg(errp, "Invalid content length: %u", byte_count); 18599d423f1SLei He return -1; 18699d423f1SLei He } 18799d423f1SLei He while (byte_count--) { 18899d423f1SLei He vlen <<= 8; 18999d423f1SLei He vlen += qcrypto_der_cut_byte(data, dlen); 19099d423f1SLei He } 19199d423f1SLei He 19299d423f1SLei He if (vlen > *dlen) { 19399d423f1SLei He error_setg(errp, "Invalid content length: %zu", vlen); 19499d423f1SLei He return -1; 19599d423f1SLei He } 19699d423f1SLei He 19799d423f1SLei He value = *data; 19899d423f1SLei He qcrypto_der_cut_nbytes(data, dlen, vlen); 19999d423f1SLei He 20099d423f1SLei He if (qcrypto_der_invoke_callback(cb, ctx, value, vlen, errp) != 0) { 20199d423f1SLei He return -1; 20299d423f1SLei He } 20399d423f1SLei He return vlen; 20499d423f1SLei He } 20599d423f1SLei He 20699d423f1SLei He static int qcrypto_der_extract_data(const uint8_t **data, size_t *dlen, 20799d423f1SLei He QCryptoDERDecodeCb cb, void *ctx, 20899d423f1SLei He Error **errp) 20999d423f1SLei He { 21099d423f1SLei He uint8_t val; 21199d423f1SLei He if (*dlen < 1) { 21299d423f1SLei He error_setg(errp, "Need more data"); 21399d423f1SLei He return -1; 21499d423f1SLei He } 21599d423f1SLei He val = qcrypto_der_peek_byte(data, dlen); 21699d423f1SLei He 21799d423f1SLei He /* must use definite length format */ 21899d423f1SLei He if (val == QCRYPTO_DER_SHORT_LEN_MASK) { 21999d423f1SLei He error_setg(errp, "Only definite length format is allowed"); 22099d423f1SLei He return -1; 22199d423f1SLei He } 22299d423f1SLei He 22399d423f1SLei He return qcrypto_der_extract_definite_data(data, dlen, cb, ctx, errp); 22499d423f1SLei He } 22599d423f1SLei He 226*3b34ccadSLei He static int qcrypto_der_decode_tlv(const uint8_t expected_tag, 227*3b34ccadSLei He const uint8_t **data, size_t *dlen, 228*3b34ccadSLei He QCryptoDERDecodeCb cb, 229*3b34ccadSLei He void *ctx, Error **errp) 23099d423f1SLei He { 231*3b34ccadSLei He const uint8_t *saved_data = *data; 232*3b34ccadSLei He size_t saved_dlen = *dlen; 23399d423f1SLei He uint8_t tag; 234*3b34ccadSLei He int data_length; 235*3b34ccadSLei He 23699d423f1SLei He if (*dlen < 1) { 23799d423f1SLei He error_setg(errp, "Need more data"); 23899d423f1SLei He return -1; 23999d423f1SLei He } 24099d423f1SLei He tag = qcrypto_der_cut_byte(data, dlen); 241*3b34ccadSLei He if (tag != expected_tag) { 242*3b34ccadSLei He error_setg(errp, "Unexpected tag: expected: %u, actual: %u", 243*3b34ccadSLei He expected_tag, tag); 244*3b34ccadSLei He goto error; 245*3b34ccadSLei He } 24699d423f1SLei He 247*3b34ccadSLei He data_length = qcrypto_der_extract_data(data, dlen, cb, ctx, errp); 248*3b34ccadSLei He if (data_length < 0) { 249*3b34ccadSLei He goto error; 250*3b34ccadSLei He } 251*3b34ccadSLei He return data_length; 252*3b34ccadSLei He 253*3b34ccadSLei He error: 254*3b34ccadSLei He *data = saved_data; 255*3b34ccadSLei He *dlen = saved_dlen; 25699d423f1SLei He return -1; 25799d423f1SLei He } 25899d423f1SLei He 259*3b34ccadSLei He int qcrypto_der_decode_int(const uint8_t **data, size_t *dlen, 260*3b34ccadSLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 261*3b34ccadSLei He { 262*3b34ccadSLei He const uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 263*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 264*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_INT); 265*3b34ccadSLei He return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 26699d423f1SLei He } 26799d423f1SLei He 26899d423f1SLei He int qcrypto_der_decode_seq(const uint8_t **data, size_t *dlen, 26999d423f1SLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 27099d423f1SLei He { 271*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 272*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_CONS, 273*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_SEQ); 274*3b34ccadSLei He return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 27599d423f1SLei He } 27699d423f1SLei He 277*3b34ccadSLei He int qcrypto_der_decode_octet_str(const uint8_t **data, size_t *dlen, 278*3b34ccadSLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 279*3b34ccadSLei He { 280*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 281*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 282*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_OCT_STR); 283*3b34ccadSLei He return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 284*3b34ccadSLei He } 285*3b34ccadSLei He 286*3b34ccadSLei He int qcrypto_der_decode_bit_str(const uint8_t **data, size_t *dlen, 287*3b34ccadSLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 288*3b34ccadSLei He { 289*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 290*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 291*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_BIT_STR); 292*3b34ccadSLei He return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 293*3b34ccadSLei He } 294*3b34ccadSLei He 295*3b34ccadSLei He int qcrypto_der_decode_oid(const uint8_t **data, size_t *dlen, 296*3b34ccadSLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 297*3b34ccadSLei He { 298*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 299*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 300*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_OID); 301*3b34ccadSLei He return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 302*3b34ccadSLei He } 303*3b34ccadSLei He 304*3b34ccadSLei He int qcrypto_der_decode_ctx_tag(const uint8_t **data, size_t *dlen, int tag_id, 305*3b34ccadSLei He QCryptoDERDecodeCb cb, void *ctx, Error **errp) 306*3b34ccadSLei He { 307*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_CONT, 308*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_CONS, 309*3b34ccadSLei He tag_id); 310*3b34ccadSLei He return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); 311*3b34ccadSLei He } 312*3b34ccadSLei He 313*3b34ccadSLei He static void qcrypto_der_encode_prim(QCryptoEncodeContext *ctx, uint8_t tag, 314*3b34ccadSLei He const uint8_t *data, size_t dlen) 315*3b34ccadSLei He { 316*3b34ccadSLei He QCryptoDerEncodeNode *node = g_new0(QCryptoDerEncodeNode, 1); 317*3b34ccadSLei He size_t nbytes_len; 318*3b34ccadSLei He 319*3b34ccadSLei He node->tag = tag; 320*3b34ccadSLei He node->data = data; 321*3b34ccadSLei He node->dlen = dlen; 322*3b34ccadSLei He node->parent = ctx->current_parent; 323*3b34ccadSLei He 324*3b34ccadSLei He qcrypto_der_encode_length(dlen, NULL, &nbytes_len); 325*3b34ccadSLei He /* 1 byte for Tag, nbyte_len for Length, and dlen for Value */ 326*3b34ccadSLei He node->parent->dlen += 1 + nbytes_len + dlen; 327*3b34ccadSLei He 328*3b34ccadSLei He ctx->tail->next = node; 329*3b34ccadSLei He ctx->tail = node; 330*3b34ccadSLei He } 331*3b34ccadSLei He 332*3b34ccadSLei He QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void) 333*3b34ccadSLei He { 334*3b34ccadSLei He QCryptoEncodeContext *ctx = g_new0(QCryptoEncodeContext, 1); 335*3b34ccadSLei He ctx->current_parent = &ctx->root; 336*3b34ccadSLei He ctx->tail = &ctx->root; 337*3b34ccadSLei He return ctx; 338*3b34ccadSLei He } 339*3b34ccadSLei He 340*3b34ccadSLei He static void qcrypto_der_encode_cons_begin(QCryptoEncodeContext *ctx, 341*3b34ccadSLei He uint8_t tag) 342*3b34ccadSLei He { 343*3b34ccadSLei He QCryptoDerEncodeNode *node = g_new0(QCryptoDerEncodeNode, 1); 344*3b34ccadSLei He 345*3b34ccadSLei He node->tag = tag; 346*3b34ccadSLei He node->parent = ctx->current_parent; 347*3b34ccadSLei He ctx->current_parent = node; 348*3b34ccadSLei He ctx->tail->next = node; 349*3b34ccadSLei He ctx->tail = node; 350*3b34ccadSLei He } 351*3b34ccadSLei He 352*3b34ccadSLei He static void qcrypto_der_encode_cons_end(QCryptoEncodeContext *ctx) 353*3b34ccadSLei He { 354*3b34ccadSLei He QCryptoDerEncodeNode *cons_node = ctx->current_parent; 355*3b34ccadSLei He size_t nbytes_len; 356*3b34ccadSLei He 357*3b34ccadSLei He qcrypto_der_encode_length(cons_node->dlen, NULL, &nbytes_len); 358*3b34ccadSLei He /* 1 byte for Tag, nbyte_len for Length, and dlen for Value */ 359*3b34ccadSLei He cons_node->parent->dlen += 1 + nbytes_len + cons_node->dlen; 360*3b34ccadSLei He ctx->current_parent = cons_node->parent; 361*3b34ccadSLei He } 362*3b34ccadSLei He 363*3b34ccadSLei He void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx) 364*3b34ccadSLei He { 365*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 366*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_CONS, 367*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_SEQ); 368*3b34ccadSLei He qcrypto_der_encode_cons_begin(ctx, tag); 369*3b34ccadSLei He } 370*3b34ccadSLei He 371*3b34ccadSLei He void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx) 372*3b34ccadSLei He { 373*3b34ccadSLei He qcrypto_der_encode_cons_end(ctx); 374*3b34ccadSLei He } 375*3b34ccadSLei He 376*3b34ccadSLei He void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx, 377*3b34ccadSLei He const uint8_t *src, size_t src_len) 378*3b34ccadSLei He { 379*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 380*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 381*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_OID); 382*3b34ccadSLei He qcrypto_der_encode_prim(ctx, tag, src, src_len); 383*3b34ccadSLei He } 384*3b34ccadSLei He 385*3b34ccadSLei He void qcrypto_der_encode_int(QCryptoEncodeContext *ctx, 386*3b34ccadSLei He const uint8_t *src, size_t src_len) 387*3b34ccadSLei He { 388*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 389*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 390*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_INT); 391*3b34ccadSLei He qcrypto_der_encode_prim(ctx, tag, src, src_len); 392*3b34ccadSLei He } 393*3b34ccadSLei He 394*3b34ccadSLei He void qcrypto_der_encode_null(QCryptoEncodeContext *ctx) 395*3b34ccadSLei He { 396*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 397*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 398*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_NULL); 399*3b34ccadSLei He qcrypto_der_encode_prim(ctx, tag, NULL, 0); 400*3b34ccadSLei He } 401*3b34ccadSLei He 402*3b34ccadSLei He void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, 403*3b34ccadSLei He const uint8_t *src, size_t src_len) 404*3b34ccadSLei He { 405*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 406*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 407*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_OCT_STR); 408*3b34ccadSLei He qcrypto_der_encode_prim(ctx, tag, src, src_len); 409*3b34ccadSLei He } 410*3b34ccadSLei He 411*3b34ccadSLei He void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx) 412*3b34ccadSLei He { 413*3b34ccadSLei He uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, 414*3b34ccadSLei He QCRYPTO_DER_TAG_ENC_PRIM, 415*3b34ccadSLei He QCRYPTO_DER_TYPE_TAG_OCT_STR); 416*3b34ccadSLei He qcrypto_der_encode_cons_begin(ctx, tag); 417*3b34ccadSLei He } 418*3b34ccadSLei He 419*3b34ccadSLei He void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx) 420*3b34ccadSLei He { 421*3b34ccadSLei He qcrypto_der_encode_cons_end(ctx); 422*3b34ccadSLei He } 423*3b34ccadSLei He 424*3b34ccadSLei He size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx) 425*3b34ccadSLei He { 426*3b34ccadSLei He return ctx->root.dlen; 427*3b34ccadSLei He } 428*3b34ccadSLei He 429*3b34ccadSLei He void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx, 430*3b34ccadSLei He uint8_t *dst) 431*3b34ccadSLei He { 432*3b34ccadSLei He QCryptoDerEncodeNode *node, *prev; 433*3b34ccadSLei He size_t len; 434*3b34ccadSLei He 435*3b34ccadSLei He for (prev = &ctx->root; 436*3b34ccadSLei He (node = prev->next) && (prev->next = node->next, 1);) { 437*3b34ccadSLei He /* Tag */ 438*3b34ccadSLei He *dst++ = node->tag; 439*3b34ccadSLei He 440*3b34ccadSLei He /* Length */ 441*3b34ccadSLei He qcrypto_der_encode_length(node->dlen, dst, &len); 442*3b34ccadSLei He dst += len; 443*3b34ccadSLei He 444*3b34ccadSLei He /* Value */ 445*3b34ccadSLei He if (node->data) { 446*3b34ccadSLei He memcpy(dst, node->data, node->dlen); 447*3b34ccadSLei He dst += node->dlen; 448*3b34ccadSLei He } 449*3b34ccadSLei He g_free(node); 450*3b34ccadSLei He } 451*3b34ccadSLei He g_free(ctx); 45299d423f1SLei He } 453