File Coverage

src/ssl/ssl_scert_single_rsa.c
Criterion Covered Total %
statement 36 51 70.5
branch 9 20 45.0
condition n/a
subroutine n/a
pod n/a
total 45 71 63.3


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2016 Thomas Pornin
3             *
4             * Permission is hereby granted, free of charge, to any person obtaining
5             * a copy of this software and associated documentation files (the
6             * "Software"), to deal in the Software without restriction, including
7             * without limitation the rights to use, copy, modify, merge, publish,
8             * distribute, sublicense, and/or sell copies of the Software, and to
9             * permit persons to whom the Software is furnished to do so, subject to
10             * the following conditions:
11             *
12             * The above copyright notice and this permission notice shall be
13             * included in all copies or substantial portions of the Software.
14             *
15             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19             * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20             * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21             * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22             * SOFTWARE.
23             */
24              
25             #include "inner.h"
26              
27             static int
28 1           sr_choose(const br_ssl_server_policy_class **pctx,
29             const br_ssl_server_context *cc,
30             br_ssl_server_choices *choices)
31             {
32             br_ssl_server_policy_rsa_context *pc;
33             const br_suite_translated *st;
34             size_t u, st_num;
35             unsigned hash_id;
36             int fh;
37              
38 1           pc = (br_ssl_server_policy_rsa_context *)pctx;
39 1           st = br_ssl_server_get_client_suites(cc, &st_num);
40 1 50         if (cc->eng.session.version < BR_TLS12) {
41 0           hash_id = 0;
42 0           fh = 1;
43             } else {
44 1           hash_id = br_ssl_choose_hash(
45             br_ssl_server_get_client_hashes(cc));
46 1           fh = (hash_id != 0);
47             }
48 1           choices->chain = pc->chain;
49 1           choices->chain_len = pc->chain_len;
50 1 50         for (u = 0; u < st_num; u ++) {
51             unsigned tt;
52              
53 1           tt = st[u][1];
54 1           switch (tt >> 12) {
55 0           case BR_SSLKEYX_RSA:
56 0 0         if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0) {
57 0           choices->cipher_suite = st[u][0];
58 0           return 1;
59             }
60 0           break;
61 1           case BR_SSLKEYX_ECDHE_RSA:
62 1 50         if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 && fh) {
    50          
63 1           choices->cipher_suite = st[u][0];
64 1           choices->algo_id = hash_id + 0xFF00;
65 1           return 1;
66             }
67 0           break;
68             }
69             }
70 0           return 0;
71             }
72              
73             static uint32_t
74 0           sr_do_keyx(const br_ssl_server_policy_class **pctx,
75             unsigned char *data, size_t *len)
76             {
77             br_ssl_server_policy_rsa_context *pc;
78              
79 0           pc = (br_ssl_server_policy_rsa_context *)pctx;
80 0           return br_rsa_ssl_decrypt(pc->irsacore, pc->sk, data, *len);
81             }
82              
83             /*
84             * OID for hash functions in RSA signatures.
85             */
86             static const unsigned char HASH_OID_SHA1[] = {
87             0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A
88             };
89              
90             static const unsigned char HASH_OID_SHA224[] = {
91             0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04
92             };
93              
94             static const unsigned char HASH_OID_SHA256[] = {
95             0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
96             };
97              
98             static const unsigned char HASH_OID_SHA384[] = {
99             0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
100             };
101              
102             static const unsigned char HASH_OID_SHA512[] = {
103             0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
104             };
105              
106             static const unsigned char *HASH_OID[] = {
107             HASH_OID_SHA1,
108             HASH_OID_SHA224,
109             HASH_OID_SHA256,
110             HASH_OID_SHA384,
111             HASH_OID_SHA512
112             };
113              
114             static size_t
115 1           sr_do_sign(const br_ssl_server_policy_class **pctx,
116             unsigned algo_id, unsigned char *data, size_t hv_len, size_t len)
117             {
118             br_ssl_server_policy_rsa_context *pc;
119             unsigned char hv[64];
120             size_t sig_len;
121             const unsigned char *hash_oid;
122              
123 1           pc = (br_ssl_server_policy_rsa_context *)pctx;
124 1           memcpy(hv, data, hv_len);
125 1           algo_id &= 0xFF;
126 1 50         if (algo_id == 0) {
127 0           hash_oid = NULL;
128 1 50         } else if (algo_id >= 2 && algo_id <= 6) {
    50          
129 1           hash_oid = HASH_OID[algo_id - 2];
130             } else {
131 0           return 0;
132             }
133 1           sig_len = (pc->sk->n_bitlen + 7) >> 3;
134 1 50         if (len < sig_len) {
135 0           return 0;
136             }
137 1 50         return pc->irsasign(hash_oid, hv, hv_len, pc->sk, data) ? sig_len : 0;
138             }
139              
140             static const br_ssl_server_policy_class sr_policy_vtable = {
141             sizeof(br_ssl_server_policy_rsa_context),
142             sr_choose,
143             sr_do_keyx,
144             sr_do_sign
145             };
146              
147             /* see bearssl_ssl.h */
148             void
149 1           br_ssl_server_set_single_rsa(br_ssl_server_context *cc,
150             const br_x509_certificate *chain, size_t chain_len,
151             const br_rsa_private_key *sk, unsigned allowed_usages,
152             br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign)
153             {
154 1           cc->chain_handler.single_rsa.vtable = &sr_policy_vtable;
155 1           cc->chain_handler.single_rsa.chain = chain;
156 1           cc->chain_handler.single_rsa.chain_len = chain_len;
157 1           cc->chain_handler.single_rsa.sk = sk;
158 1           cc->chain_handler.single_rsa.allowed_usages = allowed_usages;
159 1           cc->chain_handler.single_rsa.irsacore = irsacore;
160 1           cc->chain_handler.single_rsa.irsasign = irsasign;
161 1           cc->policy_vtable = &cc->chain_handler.single_rsa.vtable;
162 1           }