xref: /qemu/crypto/der.h (revision 940bb5fa)
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_octet_str_begin:
247  * @ctx: the encode context.
248  *
249  * Start encoding a octet string, All fields between
250  * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end
251  * are encoded as an octet string. This is useful when we need to encode a
252  * encoded SEQUENCE as OCTET STRING.
253  */
254 void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx);
255 
256 /**
257  * qcrypto_der_encode_octet_str_end:
258  * @ctx: the encode context.
259  *
260  * Finish encoding a octet string, All fields between
261  * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end
262  * are encoded as an octet string. This is useful when we need to encode a
263  * encoded SEQUENCE as OCTET STRING.
264  */
265 void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx);
266 
267 /**
268  * qcrypto_der_encode_ctx_buffer_len:
269  * @ctx: the encode context.
270  *
271  * Compute the expected buffer size to save all encoded things.
272  */
273 size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx);
274 
275 /**
276  * qcrypto_der_encode_ctx_flush_and_free:
277  * @ctx: the encode context.
278  * @dst: the destination to save the encoded data, the length of dst should
279  * not less than qcrypto_der_encode_cxt_buffer_len
280  *
281  * Flush all encoded data into dst, then free ctx.
282  */
283 void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx,
284                                            uint8_t *dst);
285 
286 #endif  /* QCRYPTO_ASN1_DECODER_H */
287