1 /* 2 * Copyright (c) 2022 Bytedance 3 * Author: lei he <helei.sig11@bytedance.com> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 #ifndef QCRYPTO_ASN1_DECODER_H 21 #define QCRYPTO_ASN1_DECODER_H 22 23 #include "qapi/error.h" 24 25 typedef struct QCryptoEncodeContext QCryptoEncodeContext; 26 27 /* rsaEncryption: 1.2.840.113549.1.1.1 */ 28 #define QCRYPTO_OID_rsaEncryption "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01" 29 30 /* Simple decoder used to parse DER encoded rsa keys. */ 31 32 /** 33 * @opaque: user context. 34 * @value: the starting address of |value| part of 'Tag-Length-Value' pattern. 35 * @vlen: length of the |value|. 36 * Returns: 0 for success, any other value is considered an error. 37 */ 38 typedef int (*QCryptoDERDecodeCb) (void *opaque, const uint8_t *value, 39 size_t vlen, Error **errp); 40 41 /** 42 * qcrypto_der_decode_int: 43 * @data: pointer to address of input data 44 * @dlen: pointer to length of input data 45 * @cb: callback invoked when decode succeed, if cb equals NULL, no 46 * callback will be invoked 47 * @opaque: parameter passed to cb 48 * 49 * Decode integer from DER-encoded data. 50 * 51 * Returns: On success, *data points to rest data, and *dlen 52 * will be set to the rest length of data, if cb is not NULL, must 53 * return 0 to make decode success, at last, the length of the data 54 * part of the decoded INTEGER will be returned. Otherwise, -1 is 55 * returned and the valued of *data and *dlen keep unchanged. 56 */ 57 int qcrypto_der_decode_int(const uint8_t **data, 58 size_t *dlen, 59 QCryptoDERDecodeCb cb, 60 void *opaque, 61 Error **errp); 62 /** 63 * qcrypto_der_decode_seq: 64 * 65 * Decode sequence from DER-encoded data, similar with der_decode_int. 66 * 67 * @data: pointer to address of input data 68 * @dlen: pointer to length of input data 69 * @cb: callback invoked when decode succeed, if cb equals NULL, no 70 * callback will be invoked 71 * @opaque: parameter passed to cb 72 * 73 * Returns: On success, *data points to rest data, and *dlen 74 * will be set to the rest length of data, if cb is not NULL, must 75 * return 0 to make decode success, at last, the length of the data 76 * part of the decoded SEQUENCE will be returned. Otherwise, -1 is 77 * returned and the valued of *data and *dlen keep unchanged. 78 */ 79 int qcrypto_der_decode_seq(const uint8_t **data, 80 size_t *dlen, 81 QCryptoDERDecodeCb cb, 82 void *opaque, 83 Error **errp); 84 85 /** 86 * qcrypto_der_decode_oid: 87 * 88 * Decode OID from DER-encoded data, similar with der_decode_int. 89 * 90 * @data: pointer to address of input data 91 * @dlen: pointer to length of input data 92 * @cb: callback invoked when decode succeed, if cb equals NULL, no 93 * callback will be invoked 94 * @opaque: parameter passed to cb 95 * 96 * Returns: On success, *data points to rest data, and *dlen 97 * will be set to the rest length of data, if cb is not NULL, must 98 * return 0 to make decode success, at last, the length of the data 99 * part of the decoded OID will be returned. Otherwise, -1 is 100 * returned and the valued of *data and *dlen keep unchanged. 101 */ 102 int qcrypto_der_decode_oid(const uint8_t **data, 103 size_t *dlen, 104 QCryptoDERDecodeCb cb, 105 void *opaque, 106 Error **errp); 107 108 /** 109 * qcrypto_der_decode_octet_str: 110 * 111 * Decode OCTET STRING from DER-encoded data, similar with der_decode_int. 112 * 113 * @data: pointer to address of input data 114 * @dlen: pointer to length of input data 115 * @cb: callback invoked when decode succeed, if cb equals NULL, no 116 * callback will be invoked 117 * @opaque: parameter passed to cb 118 * 119 * Returns: On success, *data points to rest data, and *dlen 120 * will be set to the rest length of data, if cb is not NULL, must 121 * return 0 to make decode success, at last, the length of the data 122 * part of the decoded OCTET STRING will be returned. Otherwise, -1 is 123 * returned and the valued of *data and *dlen keep unchanged. 124 */ 125 int qcrypto_der_decode_octet_str(const uint8_t **data, 126 size_t *dlen, 127 QCryptoDERDecodeCb cb, 128 void *opaque, 129 Error **errp); 130 131 /** 132 * qcrypto_der_decode_bit_str: 133 * 134 * Decode BIT STRING from DER-encoded data, similar with der_decode_int. 135 * 136 * @data: pointer to address of input data 137 * @dlen: pointer to length of input data 138 * @cb: callback invoked when decode succeed, if cb equals NULL, no 139 * callback will be invoked 140 * @opaque: parameter passed to cb 141 * 142 * Returns: On success, *data points to rest data, and *dlen 143 * will be set to the rest length of data, if cb is not NULL, must 144 * return 0 to make decode success, at last, the length of the data 145 * part of the decoded BIT STRING will be returned. Otherwise, -1 is 146 * returned and the valued of *data and *dlen keep unchanged. 147 */ 148 int qcrypto_der_decode_bit_str(const uint8_t **data, 149 size_t *dlen, 150 QCryptoDERDecodeCb cb, 151 void *opaque, 152 Error **errp); 153 154 155 /** 156 * qcrypto_der_decode_ctx_tag: 157 * 158 * Decode context specific tag 159 * 160 * @data: pointer to address of input data 161 * @dlen: pointer to length of input data 162 * @tag: expected value of context specific tag 163 * @cb: callback invoked when decode succeed, if cb equals NULL, no 164 * callback will be invoked 165 * @opaque: parameter passed to cb 166 * 167 * Returns: On success, *data points to rest data, and *dlen 168 * will be set to the rest length of data, if cb is not NULL, must 169 * return 0 to make decode success, at last, the length of the data 170 * part of the decoded BIT STRING will be returned. Otherwise, -1 is 171 * returned and the valued of *data and *dlen keep unchanged. 172 */ 173 int qcrypto_der_decode_ctx_tag(const uint8_t **data, 174 size_t *dlen, int tag_id, 175 QCryptoDERDecodeCb cb, 176 void *opaque, 177 Error **errp); 178 179 /** 180 * qcrypto_der_encode_ctx_new: 181 * 182 * Allocate a context used for der encoding. 183 */ 184 QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void); 185 186 /** 187 * qcrypto_der_encode_seq_begin: 188 * @ctx: the encode context. 189 * 190 * Start encoding a SEQUENCE for ctx. 191 * 192 */ 193 void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx); 194 195 /** 196 * qcrypto_der_encode_seq_begin: 197 * @ctx: the encode context. 198 * 199 * Finish uencoding a SEQUENCE for ctx. 200 * 201 */ 202 void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx); 203 204 205 /** 206 * qcrypto_der_encode_oid: 207 * @ctx: the encode context. 208 * @src: the source data of oid, note it should be already encoded, this 209 * function only add tag and length part for it. 210 * 211 * Encode an oid into ctx. 212 */ 213 void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx, 214 const uint8_t *src, size_t src_len); 215 216 /** 217 * qcrypto_der_encode_int: 218 * @ctx: the encode context. 219 * @src: the source data of integer, note it should be already encoded, this 220 * function only add tag and length part for it. 221 * 222 * Encode an integer into ctx. 223 */ 224 void qcrypto_der_encode_int(QCryptoEncodeContext *ctx, 225 const uint8_t *src, size_t src_len); 226 227 /** 228 * qcrypto_der_encode_null: 229 * @ctx: the encode context. 230 * 231 * Encode a null into ctx. 232 */ 233 void qcrypto_der_encode_null(QCryptoEncodeContext *ctx); 234 235 /** 236 * qcrypto_der_encode_octet_str: 237 * @ctx: the encode context. 238 * @src: the source data of the octet string. 239 * 240 * Encode a octet string into ctx. 241 */ 242 void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, 243 const uint8_t *src, size_t src_len); 244 245 /** 246 * qcrypto_der_encode_ctx_buffer_len: 247 * @ctx: the encode context. 248 * 249 * Compute the expected buffer size to save all encoded things. 250 */ 251 size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx); 252 253 /** 254 * qcrypto_der_encode_ctx_flush_and_free: 255 * @ctx: the encode context. 256 * @dst: the destination to save the encoded data, the length of dst should 257 * not less than qcrypto_der_encode_cxt_buffer_len 258 * 259 * Flush all encoded data into dst, then free ctx. 260 */ 261 void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx, 262 uint8_t *dst); 263 264 #endif /* QCRYPTO_ASN1_DECODER_H */ 265