199d423f1SLei He /* 299d423f1SLei He * Copyright (c) 2022 Bytedance 399d423f1SLei He * Author: lei he <helei.sig11@bytedance.com> 499d423f1SLei He * 599d423f1SLei He * This library is free software; you can redistribute it and/or 699d423f1SLei He * modify it under the terms of the GNU Lesser General Public 799d423f1SLei He * License as published by the Free Software Foundation; either 899d423f1SLei He * version 2.1 of the License, or (at your option) any later version. 999d423f1SLei He * 1099d423f1SLei He * This library is distributed in the hope that it will be useful, 1199d423f1SLei He * but WITHOUT ANY WARRANTY; without even the implied warranty of 1299d423f1SLei He * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1399d423f1SLei He * Lesser General Public License for more details. 1499d423f1SLei He * 1599d423f1SLei He * You should have received a copy of the GNU Lesser General Public 1699d423f1SLei He * License along with this library; if not, see <http://www.gnu.org/licenses/>. 1799d423f1SLei He * 1899d423f1SLei He */ 1999d423f1SLei He 2099d423f1SLei He #ifndef QCRYPTO_ASN1_DECODER_H 2199d423f1SLei He #define QCRYPTO_ASN1_DECODER_H 2299d423f1SLei He 2399d423f1SLei He #include "qapi/error.h" 2499d423f1SLei He 253b34ccadSLei He typedef struct QCryptoEncodeContext QCryptoEncodeContext; 263b34ccadSLei He 273b34ccadSLei He /* rsaEncryption: 1.2.840.113549.1.1.1 */ 283b34ccadSLei He #define QCRYPTO_OID_rsaEncryption "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01" 293b34ccadSLei He 3099d423f1SLei He /* Simple decoder used to parse DER encoded rsa keys. */ 3199d423f1SLei He 3299d423f1SLei He /** 3399d423f1SLei He * @opaque: user context. 3499d423f1SLei He * @value: the starting address of |value| part of 'Tag-Length-Value' pattern. 3599d423f1SLei He * @vlen: length of the |value|. 3699d423f1SLei He * Returns: 0 for success, any other value is considered an error. 3799d423f1SLei He */ 3899d423f1SLei He typedef int (*QCryptoDERDecodeCb) (void *opaque, const uint8_t *value, 3999d423f1SLei He size_t vlen, Error **errp); 4099d423f1SLei He 4199d423f1SLei He /** 4299d423f1SLei He * qcrypto_der_decode_int: 4399d423f1SLei He * @data: pointer to address of input data 4499d423f1SLei He * @dlen: pointer to length of input data 4599d423f1SLei He * @cb: callback invoked when decode succeed, if cb equals NULL, no 4699d423f1SLei He * callback will be invoked 4799d423f1SLei He * @opaque: parameter passed to cb 4899d423f1SLei He * 4999d423f1SLei He * Decode integer from DER-encoded data. 5099d423f1SLei He * 5199d423f1SLei He * Returns: On success, *data points to rest data, and *dlen 5299d423f1SLei He * will be set to the rest length of data, if cb is not NULL, must 5399d423f1SLei He * return 0 to make decode success, at last, the length of the data 5499d423f1SLei He * part of the decoded INTEGER will be returned. Otherwise, -1 is 553b34ccadSLei He * returned and the valued of *data and *dlen keep unchanged. 5699d423f1SLei He */ 5799d423f1SLei He int qcrypto_der_decode_int(const uint8_t **data, 5899d423f1SLei He size_t *dlen, 5999d423f1SLei He QCryptoDERDecodeCb cb, 6099d423f1SLei He void *opaque, 6199d423f1SLei He Error **errp); 6299d423f1SLei He /** 6399d423f1SLei He * qcrypto_der_decode_seq: 6499d423f1SLei He * 6599d423f1SLei He * Decode sequence from DER-encoded data, similar with der_decode_int. 6699d423f1SLei He * 6799d423f1SLei He * @data: pointer to address of input data 6899d423f1SLei He * @dlen: pointer to length of input data 6999d423f1SLei He * @cb: callback invoked when decode succeed, if cb equals NULL, no 7099d423f1SLei He * callback will be invoked 7199d423f1SLei He * @opaque: parameter passed to cb 7299d423f1SLei He * 7399d423f1SLei He * Returns: On success, *data points to rest data, and *dlen 7499d423f1SLei He * will be set to the rest length of data, if cb is not NULL, must 7599d423f1SLei He * return 0 to make decode success, at last, the length of the data 7699d423f1SLei He * part of the decoded SEQUENCE will be returned. Otherwise, -1 is 773b34ccadSLei He * returned and the valued of *data and *dlen keep unchanged. 7899d423f1SLei He */ 7999d423f1SLei He int qcrypto_der_decode_seq(const uint8_t **data, 8099d423f1SLei He size_t *dlen, 8199d423f1SLei He QCryptoDERDecodeCb cb, 8299d423f1SLei He void *opaque, 8399d423f1SLei He Error **errp); 8499d423f1SLei He 853b34ccadSLei He /** 863b34ccadSLei He * qcrypto_der_decode_oid: 873b34ccadSLei He * 883b34ccadSLei He * Decode OID from DER-encoded data, similar with der_decode_int. 893b34ccadSLei He * 903b34ccadSLei He * @data: pointer to address of input data 913b34ccadSLei He * @dlen: pointer to length of input data 923b34ccadSLei He * @cb: callback invoked when decode succeed, if cb equals NULL, no 933b34ccadSLei He * callback will be invoked 943b34ccadSLei He * @opaque: parameter passed to cb 953b34ccadSLei He * 963b34ccadSLei He * Returns: On success, *data points to rest data, and *dlen 973b34ccadSLei He * will be set to the rest length of data, if cb is not NULL, must 983b34ccadSLei He * return 0 to make decode success, at last, the length of the data 993b34ccadSLei He * part of the decoded OID will be returned. Otherwise, -1 is 1003b34ccadSLei He * returned and the valued of *data and *dlen keep unchanged. 1013b34ccadSLei He */ 1023b34ccadSLei He int qcrypto_der_decode_oid(const uint8_t **data, 1033b34ccadSLei He size_t *dlen, 1043b34ccadSLei He QCryptoDERDecodeCb cb, 1053b34ccadSLei He void *opaque, 1063b34ccadSLei He Error **errp); 1073b34ccadSLei He 1083b34ccadSLei He /** 1093b34ccadSLei He * qcrypto_der_decode_octet_str: 1103b34ccadSLei He * 1113b34ccadSLei He * Decode OCTET STRING from DER-encoded data, similar with der_decode_int. 1123b34ccadSLei He * 1133b34ccadSLei He * @data: pointer to address of input data 1143b34ccadSLei He * @dlen: pointer to length of input data 1153b34ccadSLei He * @cb: callback invoked when decode succeed, if cb equals NULL, no 1163b34ccadSLei He * callback will be invoked 1173b34ccadSLei He * @opaque: parameter passed to cb 1183b34ccadSLei He * 1193b34ccadSLei He * Returns: On success, *data points to rest data, and *dlen 1203b34ccadSLei He * will be set to the rest length of data, if cb is not NULL, must 1213b34ccadSLei He * return 0 to make decode success, at last, the length of the data 1223b34ccadSLei He * part of the decoded OCTET STRING will be returned. Otherwise, -1 is 1233b34ccadSLei He * returned and the valued of *data and *dlen keep unchanged. 1243b34ccadSLei He */ 1253b34ccadSLei He int qcrypto_der_decode_octet_str(const uint8_t **data, 1263b34ccadSLei He size_t *dlen, 1273b34ccadSLei He QCryptoDERDecodeCb cb, 1283b34ccadSLei He void *opaque, 1293b34ccadSLei He Error **errp); 1303b34ccadSLei He 1313b34ccadSLei He /** 1323b34ccadSLei He * qcrypto_der_decode_bit_str: 1333b34ccadSLei He * 1343b34ccadSLei He * Decode BIT STRING from DER-encoded data, similar with der_decode_int. 1353b34ccadSLei He * 1363b34ccadSLei He * @data: pointer to address of input data 1373b34ccadSLei He * @dlen: pointer to length of input data 1383b34ccadSLei He * @cb: callback invoked when decode succeed, if cb equals NULL, no 1393b34ccadSLei He * callback will be invoked 1403b34ccadSLei He * @opaque: parameter passed to cb 1413b34ccadSLei He * 1423b34ccadSLei He * Returns: On success, *data points to rest data, and *dlen 1433b34ccadSLei He * will be set to the rest length of data, if cb is not NULL, must 1443b34ccadSLei He * return 0 to make decode success, at last, the length of the data 1453b34ccadSLei He * part of the decoded BIT STRING will be returned. Otherwise, -1 is 1463b34ccadSLei He * returned and the valued of *data and *dlen keep unchanged. 1473b34ccadSLei He */ 1483b34ccadSLei He int qcrypto_der_decode_bit_str(const uint8_t **data, 1493b34ccadSLei He size_t *dlen, 1503b34ccadSLei He QCryptoDERDecodeCb cb, 1513b34ccadSLei He void *opaque, 1523b34ccadSLei He Error **errp); 1533b34ccadSLei He 1543b34ccadSLei He 1553b34ccadSLei He /** 1563b34ccadSLei He * qcrypto_der_decode_ctx_tag: 1573b34ccadSLei He * 1583b34ccadSLei He * Decode context specific tag 1593b34ccadSLei He * 1603b34ccadSLei He * @data: pointer to address of input data 1613b34ccadSLei He * @dlen: pointer to length of input data 1623b34ccadSLei He * @tag: expected value of context specific tag 1633b34ccadSLei He * @cb: callback invoked when decode succeed, if cb equals NULL, no 1643b34ccadSLei He * callback will be invoked 1653b34ccadSLei He * @opaque: parameter passed to cb 1663b34ccadSLei He * 1673b34ccadSLei He * Returns: On success, *data points to rest data, and *dlen 1683b34ccadSLei He * will be set to the rest length of data, if cb is not NULL, must 1693b34ccadSLei He * return 0 to make decode success, at last, the length of the data 1703b34ccadSLei He * part of the decoded BIT STRING will be returned. Otherwise, -1 is 1713b34ccadSLei He * returned and the valued of *data and *dlen keep unchanged. 1723b34ccadSLei He */ 1733b34ccadSLei He int qcrypto_der_decode_ctx_tag(const uint8_t **data, 1743b34ccadSLei He size_t *dlen, int tag_id, 1753b34ccadSLei He QCryptoDERDecodeCb cb, 1763b34ccadSLei He void *opaque, 1773b34ccadSLei He Error **errp); 1783b34ccadSLei He 1793b34ccadSLei He /** 1803b34ccadSLei He * qcrypto_der_encode_ctx_new: 1813b34ccadSLei He * 1823b34ccadSLei He * Allocate a context used for der encoding. 1833b34ccadSLei He */ 1843b34ccadSLei He QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void); 1853b34ccadSLei He 1863b34ccadSLei He /** 1873b34ccadSLei He * qcrypto_der_encode_seq_begin: 1883b34ccadSLei He * @ctx: the encode context. 1893b34ccadSLei He * 1903b34ccadSLei He * Start encoding a SEQUENCE for ctx. 1913b34ccadSLei He * 1923b34ccadSLei He */ 1933b34ccadSLei He void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx); 1943b34ccadSLei He 1953b34ccadSLei He /** 1963b34ccadSLei He * qcrypto_der_encode_seq_begin: 1973b34ccadSLei He * @ctx: the encode context. 1983b34ccadSLei He * 1993b34ccadSLei He * Finish uencoding a SEQUENCE for ctx. 2003b34ccadSLei He * 2013b34ccadSLei He */ 2023b34ccadSLei He void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx); 2033b34ccadSLei He 2043b34ccadSLei He 2053b34ccadSLei He /** 2063b34ccadSLei He * qcrypto_der_encode_oid: 2073b34ccadSLei He * @ctx: the encode context. 2083b34ccadSLei He * @src: the source data of oid, note it should be already encoded, this 2093b34ccadSLei He * function only add tag and length part for it. 2103b34ccadSLei He * 2113b34ccadSLei He * Encode an oid into ctx. 2123b34ccadSLei He */ 2133b34ccadSLei He void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx, 2143b34ccadSLei He const uint8_t *src, size_t src_len); 2153b34ccadSLei He 2163b34ccadSLei He /** 2173b34ccadSLei He * qcrypto_der_encode_int: 2183b34ccadSLei He * @ctx: the encode context. 2193b34ccadSLei He * @src: the source data of integer, note it should be already encoded, this 2203b34ccadSLei He * function only add tag and length part for it. 2213b34ccadSLei He * 2223b34ccadSLei He * Encode an integer into ctx. 2233b34ccadSLei He */ 2243b34ccadSLei He void qcrypto_der_encode_int(QCryptoEncodeContext *ctx, 2253b34ccadSLei He const uint8_t *src, size_t src_len); 2263b34ccadSLei He 2273b34ccadSLei He /** 2283b34ccadSLei He * qcrypto_der_encode_null: 2293b34ccadSLei He * @ctx: the encode context. 2303b34ccadSLei He * 2313b34ccadSLei He * Encode a null into ctx. 2323b34ccadSLei He */ 2333b34ccadSLei He void qcrypto_der_encode_null(QCryptoEncodeContext *ctx); 2343b34ccadSLei He 2353b34ccadSLei He /** 2363b34ccadSLei He * qcrypto_der_encode_octet_str: 2373b34ccadSLei He * @ctx: the encode context. 2383b34ccadSLei He * @src: the source data of the octet string. 2393b34ccadSLei He * 2403b34ccadSLei He * Encode a octet string into ctx. 2413b34ccadSLei He */ 2423b34ccadSLei He void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, 2433b34ccadSLei He const uint8_t *src, size_t src_len); 2443b34ccadSLei He 2453b34ccadSLei He /** 2463b34ccadSLei He * qcrypto_der_encode_ctx_buffer_len: 2473b34ccadSLei He * @ctx: the encode context. 2483b34ccadSLei He * 2493b34ccadSLei He * Compute the expected buffer size to save all encoded things. 2503b34ccadSLei He */ 2513b34ccadSLei He size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx); 2523b34ccadSLei He 2533b34ccadSLei He /** 2543b34ccadSLei He * qcrypto_der_encode_ctx_flush_and_free: 2553b34ccadSLei He * @ctx: the encode context. 256*0a19d879SMichael Tokarev * @dst: the destination to save the encoded data, the length of dst should 2573b34ccadSLei He * not less than qcrypto_der_encode_cxt_buffer_len 2583b34ccadSLei He * 2593b34ccadSLei He * Flush all encoded data into dst, then free ctx. 2603b34ccadSLei He */ 2613b34ccadSLei He void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx, 2623b34ccadSLei He uint8_t *dst); 2633b34ccadSLei He 26499d423f1SLei He #endif /* QCRYPTO_ASN1_DECODER_H */ 265