OSDN Git Service

qdev: Fix crash in array property getter
[qmiga/qemu.git] / crypto / rsakey-builtin.c.inc
1 /*
2  * QEMU Crypto akcipher algorithms
3  *
4  * Copyright (c) 2022 Bytedance
5  * Author: lei he <helei.sig11@bytedance.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include "der.h"
23 #include "rsakey.h"
24
25 static int extract_mpi(void *ctx, const uint8_t *value,
26                        size_t vlen, Error **errp)
27 {
28     QCryptoAkCipherMPI *mpi = (QCryptoAkCipherMPI *)ctx;
29     if (vlen == 0) {
30         error_setg(errp, "Empty mpi field");
31         return -1;
32     }
33     mpi->data = g_memdup2(value, vlen);
34     mpi->len = vlen;
35     return 0;
36 }
37
38 static int extract_version(void *ctx, const uint8_t *value,
39                            size_t vlen, Error **errp)
40 {
41     uint8_t *version = (uint8_t *)ctx;
42     if (vlen != 1 || *value > 1) {
43         error_setg(errp, "Invalid rsakey version");
44         return -1;
45     }
46     *version = *value;
47     return 0;
48 }
49
50 static int extract_seq_content(void *ctx, const uint8_t *value,
51                                size_t vlen, Error **errp)
52 {
53     const uint8_t **content = (const uint8_t **)ctx;
54     if (vlen == 0) {
55         error_setg(errp, "Empty sequence");
56         return -1;
57     }
58     *content = value;
59     return 0;
60 }
61
62 /**
63  *
64  *        RsaPubKey ::= SEQUENCE {
65  *             n           INTEGER
66  *             e           INTEGER
67  *         }
68  */
69 static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_public_key_parse(
70     const uint8_t *key, size_t keylen, Error **errp)
71 {
72     QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
73     const uint8_t *seq;
74     size_t seq_length;
75     int decode_ret;
76
77     decode_ret = qcrypto_der_decode_seq(&key, &keylen,
78                                         extract_seq_content, &seq, errp);
79     if (decode_ret < 0 || keylen != 0) {
80         goto error;
81     }
82     seq_length = decode_ret;
83
84     if (qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
85                                &rsa->n, errp) < 0 ||
86         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
87                                &rsa->e, errp) < 0) {
88         goto error;
89     }
90     if (seq_length != 0) {
91         error_setg(errp, "Invalid RSA public key");
92         goto error;
93     }
94
95     return rsa;
96
97 error:
98     qcrypto_akcipher_rsakey_free(rsa);
99     return NULL;
100 }
101
102 /**
103  *        RsaPrivKey ::= SEQUENCE {
104  *             version     INTEGER
105  *             n           INTEGER
106  *             e           INTEGER
107  *             d           INTEGER
108  *             p           INTEGER
109  *             q           INTEGER
110  *             dp          INTEGER
111  *             dq          INTEGER
112  *             u           INTEGER
113  *       otherPrimeInfos   OtherPrimeInfos OPTIONAL
114  *         }
115  */
116 static QCryptoAkCipherRSAKey *qcrypto_builtin_rsa_private_key_parse(
117     const uint8_t *key, size_t keylen, Error **errp)
118 {
119     QCryptoAkCipherRSAKey *rsa = g_new0(QCryptoAkCipherRSAKey, 1);
120     uint8_t version;
121     const uint8_t *seq;
122     int decode_ret;
123     size_t seq_length;
124
125     decode_ret = qcrypto_der_decode_seq(&key, &keylen, extract_seq_content,
126                                         &seq, errp);
127     if (decode_ret < 0 || keylen != 0) {
128         goto error;
129     }
130     seq_length = decode_ret;
131
132     decode_ret = qcrypto_der_decode_int(&seq, &seq_length, extract_version,
133                                         &version, errp);
134
135     if (qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
136                                &rsa->n, errp) < 0 ||
137         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
138                                &rsa->e, errp) < 0 ||
139         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi,
140                                &rsa->d, errp) < 0 ||
141         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->p,
142                                errp) < 0 ||
143         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->q,
144                                errp) < 0 ||
145         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dp,
146                                errp) < 0 ||
147         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->dq,
148                                errp) < 0 ||
149         qcrypto_der_decode_int(&seq, &seq_length, extract_mpi, &rsa->u,
150                                errp) < 0) {
151         goto error;
152     }
153
154     /**
155      * According to the standard, otherPrimeInfos must be present for version 1.
156      * There is no strict verification here, this is to be compatible with
157      * the unit test of the kernel. TODO: remove this until linux kernel's
158      * unit-test is fixed.
159      */
160     if (version == 1 && seq_length != 0) {
161         if (qcrypto_der_decode_seq(&seq, &seq_length, NULL, NULL, errp) < 0) {
162             goto error;
163         }
164         if (seq_length != 0) {
165             goto error;
166         }
167         return rsa;
168     }
169     if (seq_length != 0) {
170         error_setg(errp, "Invalid RSA private key");
171         goto error;
172     }
173
174     return rsa;
175
176 error:
177     qcrypto_akcipher_rsakey_free(rsa);
178     return NULL;
179 }
180
181 QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse(
182     QCryptoAkCipherKeyType type, const uint8_t *key,
183     size_t keylen, Error **errp)
184 {
185     switch (type) {
186     case QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
187         return qcrypto_builtin_rsa_private_key_parse(key, keylen, errp);
188
189     case QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
190         return qcrypto_builtin_rsa_public_key_parse(key, keylen, errp);
191
192     default:
193         error_setg(errp, "Unknown key type: %d", type);
194         return NULL;
195     }
196 }