1 /* 2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 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 void 28 cc_none0(const br_ssl_client_certificate_class **pctx) 29 { 30 (void)pctx; 31 } 32 33 static void 34 cc_none1(const br_ssl_client_certificate_class **pctx, size_t len) 35 { 36 (void)pctx; 37 (void)len; 38 } 39 40 static void 41 cc_none2(const br_ssl_client_certificate_class **pctx, 42 const unsigned char *data, size_t len) 43 { 44 (void)pctx; 45 (void)data; 46 (void)len; 47 } 48 49 static void 50 cc_choose(const br_ssl_client_certificate_class **pctx, 51 const br_ssl_client_context *cc, uint32_t auth_types, 52 br_ssl_client_certificate *choices) 53 { 54 br_ssl_client_certificate_rsa_context *zc; 55 int x; 56 57 (void)cc; 58 zc = (br_ssl_client_certificate_rsa_context *)pctx; 59 x = br_ssl_choose_hash((unsigned)auth_types); 60 if (x == 0 && (auth_types & 1) == 0) { 61 memset(choices, 0, sizeof *choices); 62 } 63 choices->auth_type = BR_AUTH_RSA; 64 choices->hash_id = x; 65 choices->chain = zc->chain; 66 choices->chain_len = zc->chain_len; 67 } 68 69 /* 70 * OID for hash functions in RSA signatures. 71 */ 72 static const unsigned char HASH_OID_SHA1[] = { 73 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A 74 }; 75 76 static const unsigned char HASH_OID_SHA224[] = { 77 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 78 }; 79 80 static const unsigned char HASH_OID_SHA256[] = { 81 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 82 }; 83 84 static const unsigned char HASH_OID_SHA384[] = { 85 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 86 }; 87 88 static const unsigned char HASH_OID_SHA512[] = { 89 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 90 }; 91 92 static const unsigned char *HASH_OID[] = { 93 HASH_OID_SHA1, 94 HASH_OID_SHA224, 95 HASH_OID_SHA256, 96 HASH_OID_SHA384, 97 HASH_OID_SHA512 98 }; 99 100 static size_t 101 cc_do_sign(const br_ssl_client_certificate_class **pctx, 102 int hash_id, size_t hv_len, unsigned char *data, size_t len) 103 { 104 br_ssl_client_certificate_rsa_context *zc; 105 unsigned char hv[64]; 106 const unsigned char *hash_oid; 107 size_t sig_len; 108 109 zc = (br_ssl_client_certificate_rsa_context *)pctx; 110 memcpy(hv, data, hv_len); 111 if (hash_id == 0) { 112 hash_oid = NULL; 113 } else if (hash_id >= 2 && hash_id <= 6) { 114 hash_oid = HASH_OID[hash_id - 2]; 115 } else { 116 return 0; 117 } 118 sig_len = (zc->sk->n_bitlen + 7) >> 3; 119 if (len < sig_len) { 120 return 0; 121 } 122 return zc->irsasign(hash_oid, hv, hv_len, zc->sk, data) ? sig_len : 0; 123 } 124 125 static const br_ssl_client_certificate_class ccert_vtable = { 126 sizeof(br_ssl_client_certificate_rsa_context), 127 cc_none0, /* start_name_list */ 128 cc_none1, /* start_name */ 129 cc_none2, /* append_name */ 130 cc_none0, /* end_name */ 131 cc_none0, /* end_name_list */ 132 cc_choose, 133 0, 134 cc_do_sign 135 }; 136 137 /* see bearssl_ssl.h */ 138 void 139 br_ssl_client_set_single_rsa(br_ssl_client_context *cc, 140 const br_x509_certificate *chain, size_t chain_len, 141 const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign) 142 { 143 cc->client_auth.single_rsa.vtable = &ccert_vtable; 144 cc->client_auth.single_rsa.chain = chain; 145 cc->client_auth.single_rsa.chain_len = chain_len; 146 cc->client_auth.single_rsa.sk = sk; 147 cc->client_auth.single_rsa.irsasign = irsasign; 148 cc->client_auth_vtable = &cc->client_auth.single_rsa.vtable; 149 } 150