OLD | NEW |
1 /* | 1 /* |
2 * SSL3 Protocol | 2 * SSL3 Protocol |
3 * | 3 * |
4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | 7 |
8 /* ECC code moved here from ssl3con.c */ | 8 /* ECC code moved here from ssl3con.c */ |
9 | 9 |
10 #include "nss.h" | 10 #include "nss.h" |
11 #include "cert.h" | 11 #include "cert.h" |
12 #include "ssl.h" | 12 #include "ssl.h" |
13 #include "cryptohi.h"» /* for DSAU_ stuff */ | 13 #include "cryptohi.h" /* for DSAU_ stuff */ |
14 #include "keyhi.h" | 14 #include "keyhi.h" |
15 #include "secder.h" | 15 #include "secder.h" |
16 #include "secitem.h" | 16 #include "secitem.h" |
17 | 17 |
18 #include "sslimpl.h" | 18 #include "sslimpl.h" |
19 #include "sslproto.h" | 19 #include "sslproto.h" |
20 #include "sslerr.h" | 20 #include "sslerr.h" |
21 #include "prtime.h" | 21 #include "prtime.h" |
22 #include "prinrval.h" | 22 #include "prinrval.h" |
23 #include "prerror.h" | 23 #include "prerror.h" |
24 #include "pratom.h" | 24 #include "pratom.h" |
25 #include "prthread.h" | 25 #include "prthread.h" |
26 #include "prinit.h" | 26 #include "prinit.h" |
27 | 27 |
28 #include "pk11func.h" | 28 #include "pk11func.h" |
29 #include "secmod.h" | 29 #include "secmod.h" |
30 | 30 |
31 #include <stdio.h> | 31 #include <stdio.h> |
32 | 32 |
33 /* This is a bodge to allow this code to be compiled against older NSS headers | 33 /* This is a bodge to allow this code to be compiled against older NSS headers |
34 * that don't contain the TLS 1.2 changes. */ | 34 * that don't contain the TLS 1.2 changes. */ |
35 #ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 | 35 #ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 |
36 #define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24) | 36 #define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24) |
37 #endif | 37 #endif |
38 | 38 |
39 #ifdef NSS_ENABLE_ECC | 39 #ifndef NSS_DISABLE_ECC |
40 | 40 |
41 #ifndef PK11_SETATTRS | 41 #ifndef PK11_SETATTRS |
42 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ | 42 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ |
43 » » (x)->pValue=(v); (x)->ulValueLen = (l); | 43 (x)->pValue=(v); (x)->ulValueLen = (l); |
44 #endif | 44 #endif |
45 | 45 |
46 #define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \ | 46 #define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \ |
47 (ss->serverCerts[type].serverKeyPair ? \ | 47 (ss->serverCerts[type].serverKeyPair ? \ |
48 ss->serverCerts[type].serverKeyPair->pubKey : NULL) | 48 ss->serverCerts[type].serverKeyPair->pubKey : NULL) |
49 | 49 |
50 #define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \ | 50 #define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \ |
51 ((curveName > ec_noName) && \ | 51 ((curveName > ec_noName) && \ |
52 (curveName < ec_pastLastName) && \ | 52 (curveName < ec_pastLastName) && \ |
53 ((1UL << curveName) & curvemsk) != 0) | 53 ((1UL << curveName) & curvemsk) != 0) |
54 | 54 |
55 | 55 |
56 | 56 |
57 static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve); | 57 static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve); |
58 | 58 |
59 #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName)) | 59 #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName)) |
60 | 60 |
61 /* Table containing OID tags for elliptic curves named in the | 61 /* Table containing OID tags for elliptic curves named in the |
62 * ECC-TLS IETF draft. | 62 * ECC-TLS IETF draft. |
63 */ | 63 */ |
64 static const SECOidTag ecName2OIDTag[] = { | 64 static const SECOidTag ecName2OIDTag[] = { |
65 » 0, | 65 0, |
66 » SEC_OID_SECG_EC_SECT163K1, /* 1 */ | 66 SEC_OID_SECG_EC_SECT163K1, /* 1 */ |
67 » SEC_OID_SECG_EC_SECT163R1, /* 2 */ | 67 SEC_OID_SECG_EC_SECT163R1, /* 2 */ |
68 » SEC_OID_SECG_EC_SECT163R2, /* 3 */ | 68 SEC_OID_SECG_EC_SECT163R2, /* 3 */ |
69 » SEC_OID_SECG_EC_SECT193R1, /* 4 */ | 69 SEC_OID_SECG_EC_SECT193R1, /* 4 */ |
70 » SEC_OID_SECG_EC_SECT193R2, /* 5 */ | 70 SEC_OID_SECG_EC_SECT193R2, /* 5 */ |
71 » SEC_OID_SECG_EC_SECT233K1, /* 6 */ | 71 SEC_OID_SECG_EC_SECT233K1, /* 6 */ |
72 » SEC_OID_SECG_EC_SECT233R1, /* 7 */ | 72 SEC_OID_SECG_EC_SECT233R1, /* 7 */ |
73 » SEC_OID_SECG_EC_SECT239K1, /* 8 */ | 73 SEC_OID_SECG_EC_SECT239K1, /* 8 */ |
74 » SEC_OID_SECG_EC_SECT283K1, /* 9 */ | 74 SEC_OID_SECG_EC_SECT283K1, /* 9 */ |
75 » SEC_OID_SECG_EC_SECT283R1, /* 10 */ | 75 SEC_OID_SECG_EC_SECT283R1, /* 10 */ |
76 » SEC_OID_SECG_EC_SECT409K1, /* 11 */ | 76 SEC_OID_SECG_EC_SECT409K1, /* 11 */ |
77 » SEC_OID_SECG_EC_SECT409R1, /* 12 */ | 77 SEC_OID_SECG_EC_SECT409R1, /* 12 */ |
78 » SEC_OID_SECG_EC_SECT571K1, /* 13 */ | 78 SEC_OID_SECG_EC_SECT571K1, /* 13 */ |
79 » SEC_OID_SECG_EC_SECT571R1, /* 14 */ | 79 SEC_OID_SECG_EC_SECT571R1, /* 14 */ |
80 » SEC_OID_SECG_EC_SECP160K1, /* 15 */ | 80 SEC_OID_SECG_EC_SECP160K1, /* 15 */ |
81 » SEC_OID_SECG_EC_SECP160R1, /* 16 */ | 81 SEC_OID_SECG_EC_SECP160R1, /* 16 */ |
82 » SEC_OID_SECG_EC_SECP160R2, /* 17 */ | 82 SEC_OID_SECG_EC_SECP160R2, /* 17 */ |
83 » SEC_OID_SECG_EC_SECP192K1, /* 18 */ | 83 SEC_OID_SECG_EC_SECP192K1, /* 18 */ |
84 » SEC_OID_SECG_EC_SECP192R1, /* 19 */ | 84 SEC_OID_SECG_EC_SECP192R1, /* 19 */ |
85 » SEC_OID_SECG_EC_SECP224K1, /* 20 */ | 85 SEC_OID_SECG_EC_SECP224K1, /* 20 */ |
86 » SEC_OID_SECG_EC_SECP224R1, /* 21 */ | 86 SEC_OID_SECG_EC_SECP224R1, /* 21 */ |
87 » SEC_OID_SECG_EC_SECP256K1, /* 22 */ | 87 SEC_OID_SECG_EC_SECP256K1, /* 22 */ |
88 » SEC_OID_SECG_EC_SECP256R1, /* 23 */ | 88 SEC_OID_SECG_EC_SECP256R1, /* 23 */ |
89 » SEC_OID_SECG_EC_SECP384R1, /* 24 */ | 89 SEC_OID_SECG_EC_SECP384R1, /* 24 */ |
90 » SEC_OID_SECG_EC_SECP521R1, /* 25 */ | 90 SEC_OID_SECG_EC_SECP521R1, /* 25 */ |
91 }; | 91 }; |
92 | 92 |
93 static const PRUint16 curve2bits[] = { | 93 static const PRUint16 curve2bits[] = { |
94 » 0, /* ec_noName = 0, */ | 94 0, /* ec_noName = 0, */ |
95 » 163, /* ec_sect163k1 = 1, */ | 95 163, /* ec_sect163k1 = 1, */ |
96 » 163, /* ec_sect163r1 = 2, */ | 96 163, /* ec_sect163r1 = 2, */ |
97 » 163, /* ec_sect163r2 = 3, */ | 97 163, /* ec_sect163r2 = 3, */ |
98 » 193, /* ec_sect193r1 = 4, */ | 98 193, /* ec_sect193r1 = 4, */ |
99 » 193, /* ec_sect193r2 = 5, */ | 99 193, /* ec_sect193r2 = 5, */ |
100 » 233, /* ec_sect233k1 = 6, */ | 100 233, /* ec_sect233k1 = 6, */ |
101 » 233, /* ec_sect233r1 = 7, */ | 101 233, /* ec_sect233r1 = 7, */ |
102 » 239, /* ec_sect239k1 = 8, */ | 102 239, /* ec_sect239k1 = 8, */ |
103 » 283, /* ec_sect283k1 = 9, */ | 103 283, /* ec_sect283k1 = 9, */ |
104 » 283, /* ec_sect283r1 = 10, */ | 104 283, /* ec_sect283r1 = 10, */ |
105 » 409, /* ec_sect409k1 = 11, */ | 105 409, /* ec_sect409k1 = 11, */ |
106 » 409, /* ec_sect409r1 = 12, */ | 106 409, /* ec_sect409r1 = 12, */ |
107 » 571, /* ec_sect571k1 = 13, */ | 107 571, /* ec_sect571k1 = 13, */ |
108 » 571, /* ec_sect571r1 = 14, */ | 108 571, /* ec_sect571r1 = 14, */ |
109 » 160, /* ec_secp160k1 = 15, */ | 109 160, /* ec_secp160k1 = 15, */ |
110 » 160, /* ec_secp160r1 = 16, */ | 110 160, /* ec_secp160r1 = 16, */ |
111 » 160, /* ec_secp160r2 = 17, */ | 111 160, /* ec_secp160r2 = 17, */ |
112 » 192, /* ec_secp192k1 = 18, */ | 112 192, /* ec_secp192k1 = 18, */ |
113 » 192, /* ec_secp192r1 = 19, */ | 113 192, /* ec_secp192r1 = 19, */ |
114 » 224, /* ec_secp224k1 = 20, */ | 114 224, /* ec_secp224k1 = 20, */ |
115 » 224, /* ec_secp224r1 = 21, */ | 115 224, /* ec_secp224r1 = 21, */ |
116 » 256, /* ec_secp256k1 = 22, */ | 116 256, /* ec_secp256k1 = 22, */ |
117 » 256, /* ec_secp256r1 = 23, */ | 117 256, /* ec_secp256r1 = 23, */ |
118 » 384, /* ec_secp384r1 = 24, */ | 118 384, /* ec_secp384r1 = 24, */ |
119 » 521, /* ec_secp521r1 = 25, */ | 119 521, /* ec_secp521r1 = 25, */ |
120 65535 /* ec_pastLastName */ | 120 65535 /* ec_pastLastName */ |
121 }; | 121 }; |
122 | 122 |
123 typedef struct Bits2CurveStr { | 123 typedef struct Bits2CurveStr { |
124 PRUint16 bits; | 124 PRUint16 bits; |
125 ECName curve; | 125 ECName curve; |
126 } Bits2Curve; | 126 } Bits2Curve; |
127 | 127 |
128 static const Bits2Curve bits2curve [] = { | 128 static const Bits2Curve bits2curve [] = { |
129 {» 192, ec_secp192r1 /* = 19, fast */ }, | 129 { 192, ec_secp192r1 /* = 19, fast */ }, |
130 {» 160, ec_secp160r2 /* = 17, fast */ }, | 130 { 160, ec_secp160r2 /* = 17, fast */ }, |
131 {» 160, ec_secp160k1 /* = 15, */ }, | 131 { 160, ec_secp160k1 /* = 15, */ }, |
132 {» 160, ec_secp160r1 /* = 16, */ }, | 132 { 160, ec_secp160r1 /* = 16, */ }, |
133 {» 163, ec_sect163k1 /* = 1, */ }, | 133 { 163, ec_sect163k1 /* = 1, */ }, |
134 {» 163, ec_sect163r1 /* = 2, */ }, | 134 { 163, ec_sect163r1 /* = 2, */ }, |
135 {» 163, ec_sect163r2 /* = 3, */ }, | 135 { 163, ec_sect163r2 /* = 3, */ }, |
136 {» 192, ec_secp192k1 /* = 18, */ }, | 136 { 192, ec_secp192k1 /* = 18, */ }, |
137 {» 193, ec_sect193r1 /* = 4, */ }, | 137 { 193, ec_sect193r1 /* = 4, */ }, |
138 {» 193, ec_sect193r2 /* = 5, */ }, | 138 { 193, ec_sect193r2 /* = 5, */ }, |
139 {» 224, ec_secp224r1 /* = 21, fast */ }, | 139 { 224, ec_secp224r1 /* = 21, fast */ }, |
140 {» 224, ec_secp224k1 /* = 20, */ }, | 140 { 224, ec_secp224k1 /* = 20, */ }, |
141 {» 233, ec_sect233k1 /* = 6, */ }, | 141 { 233, ec_sect233k1 /* = 6, */ }, |
142 {» 233, ec_sect233r1 /* = 7, */ }, | 142 { 233, ec_sect233r1 /* = 7, */ }, |
143 {» 239, ec_sect239k1 /* = 8, */ }, | 143 { 239, ec_sect239k1 /* = 8, */ }, |
144 {» 256, ec_secp256r1 /* = 23, fast */ }, | 144 { 256, ec_secp256r1 /* = 23, fast */ }, |
145 {» 256, ec_secp256k1 /* = 22, */ }, | 145 { 256, ec_secp256k1 /* = 22, */ }, |
146 {» 283, ec_sect283k1 /* = 9, */ }, | 146 { 283, ec_sect283k1 /* = 9, */ }, |
147 {» 283, ec_sect283r1 /* = 10, */ }, | 147 { 283, ec_sect283r1 /* = 10, */ }, |
148 {» 384, ec_secp384r1 /* = 24, fast */ }, | 148 { 384, ec_secp384r1 /* = 24, fast */ }, |
149 {» 409, ec_sect409k1 /* = 11, */ }, | 149 { 409, ec_sect409k1 /* = 11, */ }, |
150 {» 409, ec_sect409r1 /* = 12, */ }, | 150 { 409, ec_sect409r1 /* = 12, */ }, |
151 {» 521, ec_secp521r1 /* = 25, fast */ }, | 151 { 521, ec_secp521r1 /* = 25, fast */ }, |
152 {» 571, ec_sect571k1 /* = 13, */ }, | 152 { 571, ec_sect571k1 /* = 13, */ }, |
153 {» 571, ec_sect571r1 /* = 14, */ }, | 153 { 571, ec_sect571r1 /* = 14, */ }, |
154 { 65535, ec_noName } | 154 { 65535, ec_noName } |
155 }; | 155 }; |
156 | 156 |
157 typedef struct ECDHEKeyPairStr { | 157 typedef struct ECDHEKeyPairStr { |
158 ssl3KeyPair * pair; | 158 ssl3KeyPair * pair; |
159 int error; /* error code of the call-once function */ | 159 int error; /* error code of the call-once function */ |
160 PRCallOnceType once; | 160 PRCallOnceType once; |
161 } ECDHEKeyPair; | 161 } ECDHEKeyPair; |
162 | 162 |
163 /* arrays of ECDHE KeyPairs */ | 163 /* arrays of ECDHE KeyPairs */ |
164 static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName]; | 164 static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName]; |
165 | 165 |
166 SECStatus | 166 SECStatus |
167 ssl3_ECName2Params(PLArenaPool * arena, ECName curve, SECKEYECParams * params) | 167 ssl3_ECName2Params(PLArenaPool * arena, ECName curve, SECKEYECParams * params) |
168 { | 168 { |
169 SECOidData *oidData = NULL; | 169 SECOidData *oidData = NULL; |
170 | 170 |
171 if ((curve <= ec_noName) || (curve >= ec_pastLastName) || | 171 if ((curve <= ec_noName) || (curve >= ec_pastLastName) || |
172 » ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) { | 172 ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) { |
173 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 173 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); |
174 » return SECFailure; | 174 return SECFailure; |
175 } | 175 } |
176 | 176 |
177 SECITEM_AllocItem(arena, params, (2 + oidData->oid.len)); | 177 SECITEM_AllocItem(arena, params, (2 + oidData->oid.len)); |
178 /* | 178 /* |
179 * params->data needs to contain the ASN encoding of an object ID (OID) | 179 * params->data needs to contain the ASN encoding of an object ID (OID) |
180 * representing the named curve. The actual OID is in | 180 * representing the named curve. The actual OID is in |
181 * oidData->oid.data so we simply prepend 0x06 and OID length | 181 * oidData->oid.data so we simply prepend 0x06 and OID length |
182 */ | 182 */ |
183 params->data[0] = SEC_ASN1_OBJECT_ID; | 183 params->data[0] = SEC_ASN1_OBJECT_ID; |
184 params->data[1] = oidData->oid.len; | 184 params->data[1] = oidData->oid.len; |
185 memcpy(params->data + 2, oidData->oid.data, oidData->oid.len); | 185 memcpy(params->data + 2, oidData->oid.data, oidData->oid.len); |
186 | 186 |
187 return SECSuccess; | 187 return SECSuccess; |
188 } | 188 } |
189 | 189 |
190 static ECName | 190 static ECName |
191 params2ecName(SECKEYECParams * params) | 191 params2ecName(SECKEYECParams * params) |
192 { | 192 { |
193 SECItem oid = { siBuffer, NULL, 0}; | 193 SECItem oid = { siBuffer, NULL, 0}; |
194 SECOidData *oidData = NULL; | 194 SECOidData *oidData = NULL; |
195 ECName i; | 195 ECName i; |
196 | 196 |
197 /* | 197 /* |
198 * params->data needs to contain the ASN encoding of an object ID (OID) | 198 * params->data needs to contain the ASN encoding of an object ID (OID) |
199 * representing a named curve. Here, we strip away everything | 199 * representing a named curve. Here, we strip away everything |
200 * before the actual OID and use the OID to look up a named curve. | 200 * before the actual OID and use the OID to look up a named curve. |
201 */ | 201 */ |
202 if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName; | 202 if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName; |
203 oid.len = params->len - 2; | 203 oid.len = params->len - 2; |
204 oid.data = params->data + 2; | 204 oid.data = params->data + 2; |
205 if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName; | 205 if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName; |
206 for (i = ec_noName + 1; i < ec_pastLastName; i++) { | 206 for (i = ec_noName + 1; i < ec_pastLastName; i++) { |
207 » if (ecName2OIDTag[i] == oidData->offset) | 207 if (ecName2OIDTag[i] == oidData->offset) |
208 » return i; | 208 return i; |
209 } | 209 } |
210 | 210 |
211 return ec_noName; | 211 return ec_noName; |
212 } | 212 } |
213 | 213 |
214 /* Caller must set hiLevel error code. */ | 214 /* Caller must set hiLevel error code. */ |
215 static SECStatus | 215 static SECStatus |
216 ssl3_ComputeECDHKeyHash(SECOidTag hashAlg, | 216 ssl3_ComputeECDHKeyHash(SECOidTag hashAlg, |
217 » » » SECItem ec_params, SECItem server_ecpoint, | 217 SECItem ec_params, SECItem server_ecpoint, |
218 » » » SSL3Random *client_rand, SSL3Random *server_rand, | 218 SSL3Random *client_rand, SSL3Random *server_rand, |
219 » » » SSL3Hashes *hashes, PRBool bypassPKCS11) | 219 SSL3Hashes *hashes, PRBool bypassPKCS11) |
220 { | 220 { |
221 PRUint8 * hashBuf; | 221 PRUint8 * hashBuf; |
222 PRUint8 * pBuf; | 222 PRUint8 * pBuf; |
223 SECStatus rv » » = SECSuccess; | 223 SECStatus rv = SECSuccess; |
224 unsigned int bufLen; | 224 unsigned int bufLen; |
225 /* | 225 /* |
226 * XXX For now, we only support named curves (the appropriate | 226 * XXX For now, we only support named curves (the appropriate |
227 * checks are made before this method is called) so ec_params | 227 * checks are made before this method is called) so ec_params |
228 * takes up only two bytes. ECPoint needs to fit in 256 bytes | 228 * takes up only two bytes. ECPoint needs to fit in 256 bytes |
229 * (because the spec says the length must fit in one byte) | 229 * (because the spec says the length must fit in one byte) |
230 */ | 230 */ |
231 PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256]; | 231 PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256]; |
232 | 232 |
233 bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len; | 233 bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len; |
234 if (bufLen <= sizeof buf) { | 234 if (bufLen <= sizeof buf) { |
235 » hashBuf = buf; | 235 hashBuf = buf; |
236 } else { | 236 } else { |
237 » hashBuf = PORT_Alloc(bufLen); | 237 hashBuf = PORT_Alloc(bufLen); |
238 » if (!hashBuf) { | 238 if (!hashBuf) { |
239 » return SECFailure; | 239 return SECFailure; |
240 » } | 240 } |
241 } | 241 } |
242 | 242 |
243 memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); | 243 memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH); |
244 » pBuf = hashBuf + SSL3_RANDOM_LENGTH; | 244 pBuf = hashBuf + SSL3_RANDOM_LENGTH; |
245 memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH); | 245 memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH); |
246 » pBuf += SSL3_RANDOM_LENGTH; | 246 pBuf += SSL3_RANDOM_LENGTH; |
247 memcpy(pBuf, ec_params.data, ec_params.len); | 247 memcpy(pBuf, ec_params.data, ec_params.len); |
248 » pBuf += ec_params.len; | 248 pBuf += ec_params.len; |
249 pBuf[0] = (PRUint8)(server_ecpoint.len); | 249 pBuf[0] = (PRUint8)(server_ecpoint.len); |
250 pBuf += 1; | 250 pBuf += 1; |
251 memcpy(pBuf, server_ecpoint.data, server_ecpoint.len); | 251 memcpy(pBuf, server_ecpoint.data, server_ecpoint.len); |
252 » pBuf += server_ecpoint.len; | 252 pBuf += server_ecpoint.len; |
253 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); | 253 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen); |
254 | 254 |
255 rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, | 255 rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes, |
256 » » » » bypassPKCS11); | 256 bypassPKCS11); |
257 | 257 |
258 PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen)); | 258 PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen)); |
259 PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", | 259 PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", |
260 » hashes->u.s.md5, MD5_LENGTH)); | 260 hashes->u.s.md5, MD5_LENGTH)); |
261 PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", | 261 PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", |
262 » hashes->u.s.sha, SHA1_LENGTH)); | 262 hashes->u.s.sha, SHA1_LENGTH)); |
263 | 263 |
264 if (hashBuf != buf) | 264 if (hashBuf != buf) |
265 » PORT_Free(hashBuf); | 265 PORT_Free(hashBuf); |
266 return rv; | 266 return rv; |
267 } | 267 } |
268 | 268 |
269 | 269 |
270 /* Called from ssl3_SendClientKeyExchange(). */ | 270 /* Called from ssl3_SendClientKeyExchange(). */ |
271 SECStatus | 271 SECStatus |
272 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) | 272 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) |
273 { | 273 { |
274 PK11SymKey *» pms » » = NULL; | 274 PK11SymKey * pms = NULL; |
275 SECStatus rv » » = SECFailure; | 275 SECStatus rv = SECFailure; |
276 PRBool isTLS, isTLS12; | 276 PRBool isTLS, isTLS12; |
277 CK_MECHANISM_TYPE» target; | 277 CK_MECHANISM_TYPE target; |
278 SECKEYPublicKey» *pubKey = NULL;»» /* Ephemeral ECDH key */ | 278 SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */ |
279 SECKEYPrivateKey» *privKey = NULL;» /* Ephemeral ECDH key */ | 279 SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */ |
280 | 280 |
281 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 281 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
282 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 282 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
283 | 283 |
284 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | 284 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
285 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 285 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
286 | 286 |
287 /* Generate ephemeral EC keypair */ | 287 /* Generate ephemeral EC keypair */ |
288 if (svrPubKey->keyType != ecKey) { | 288 if (svrPubKey->keyType != ecKey) { |
289 » PORT_SetError(SEC_ERROR_BAD_KEY); | 289 PORT_SetError(SEC_ERROR_BAD_KEY); |
290 » goto loser; | 290 goto loser; |
291 } | 291 } |
292 /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ | 292 /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ |
293 privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, | 293 privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, |
294 » &pubKey, ss->pkcs11PinArg); | 294 &pubKey, ss->pkcs11PinArg); |
295 if (!privKey || !pubKey) { | 295 if (!privKey || !pubKey) { |
296 » ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); | 296 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
297 » rv = SECFailure; | 297 rv = SECFailure; |
298 » goto loser; | 298 goto loser; |
299 } | 299 } |
300 PRINT_BUF(50, (ss, "ECDH public value:", | 300 PRINT_BUF(50, (ss, "ECDH public value:", |
301 » » » » » pubKey->u.ec.publicValue.data, | 301 pubKey->u.ec.publicValue.data, |
302 » » » » » pubKey->u.ec.publicValue.len)); | 302 pubKey->u.ec.publicValue.len)); |
303 | 303 |
304 if (isTLS12) { | 304 if (isTLS12) { |
305 » target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; | 305 target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; |
306 } else if (isTLS) { | 306 } else if (isTLS) { |
307 » target = CKM_TLS_MASTER_KEY_DERIVE_DH; | 307 target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
308 } else { | 308 } else { |
309 » target = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 309 target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
310 } | 310 } |
311 | 311 |
312 /* Determine the PMS */ | 312 /* Determine the PMS */ |
313 pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, | 313 pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, |
314 » » » CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, | 314 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, |
315 » » » CKD_NULL, NULL, NULL); | 315 CKD_NULL, NULL, NULL); |
316 | 316 |
317 if (pms == NULL) { | 317 if (pms == NULL) { |
318 » SSL3AlertDescription desc = illegal_parameter; | 318 SSL3AlertDescription desc = illegal_parameter; |
319 » (void)SSL3_SendAlert(ss, alert_fatal, desc); | 319 (void)SSL3_SendAlert(ss, alert_fatal, desc); |
320 » ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 320 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
321 » goto loser; | 321 goto loser; |
322 } | 322 } |
323 | 323 |
324 SECKEY_DestroyPrivateKey(privKey); | 324 SECKEY_DestroyPrivateKey(privKey); |
325 privKey = NULL; | 325 privKey = NULL; |
326 | 326 |
327 rv = ssl3_InitPendingCipherSpec(ss, pms); | 327 rv = ssl3_InitPendingCipherSpec(ss, pms); |
328 PK11_FreeSymKey(pms); pms = NULL; | 328 PK11_FreeSymKey(pms); pms = NULL; |
329 | 329 |
330 if (rv != SECSuccess) { | 330 if (rv != SECSuccess) { |
331 » ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 331 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
332 » goto loser; | 332 goto loser; |
333 } | 333 } |
334 | 334 |
335 rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, | 335 rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, |
336 » » » » » pubKey->u.ec.publicValue.len + 1); | 336 pubKey->u.ec.publicValue.len + 1); |
337 if (rv != SECSuccess) { | 337 if (rv != SECSuccess) { |
338 goto loser;» /* err set by ssl3_AppendHandshake* */ | 338 goto loser; /* err set by ssl3_AppendHandshake* */ |
339 } | 339 } |
340 | 340 |
341 rv = ssl3_AppendHandshakeVariable(ss, | 341 rv = ssl3_AppendHandshakeVariable(ss, |
342 » » » » » pubKey->u.ec.publicValue.data, | 342 pubKey->u.ec.publicValue.data, |
343 » » » » » pubKey->u.ec.publicValue.len, 1); | 343 pubKey->u.ec.publicValue.len, 1); |
344 SECKEY_DestroyPublicKey(pubKey); | 344 SECKEY_DestroyPublicKey(pubKey); |
345 pubKey = NULL; | 345 pubKey = NULL; |
346 | 346 |
347 if (rv != SECSuccess) { | 347 if (rv != SECSuccess) { |
348 goto loser;» /* err set by ssl3_AppendHandshake* */ | 348 goto loser; /* err set by ssl3_AppendHandshake* */ |
349 } | 349 } |
350 | 350 |
351 rv = SECSuccess; | 351 rv = SECSuccess; |
352 | 352 |
353 loser: | 353 loser: |
354 if(pms) PK11_FreeSymKey(pms); | 354 if(pms) PK11_FreeSymKey(pms); |
355 if(privKey) SECKEY_DestroyPrivateKey(privKey); | 355 if(privKey) SECKEY_DestroyPrivateKey(privKey); |
356 if(pubKey) SECKEY_DestroyPublicKey(pubKey); | 356 if(pubKey) SECKEY_DestroyPublicKey(pubKey); |
357 return rv; | 357 return rv; |
358 } | 358 } |
359 | 359 |
360 | 360 |
361 /* | 361 /* |
362 ** Called from ssl3_HandleClientKeyExchange() | 362 ** Called from ssl3_HandleClientKeyExchange() |
363 */ | 363 */ |
364 SECStatus | 364 SECStatus |
365 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, | 365 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, |
366 » » » » PRUint32 length, | 366 PRUint32 length, |
367 SECKEYPublicKey *srvrPubKey, | 367 SECKEYPublicKey *srvrPubKey, |
368 SECKEYPrivateKey *srvrPrivKey) | 368 SECKEYPrivateKey *srvrPrivKey) |
369 { | 369 { |
370 PK11SymKey * pms; | 370 PK11SymKey * pms; |
371 SECStatus rv; | 371 SECStatus rv; |
372 SECKEYPublicKey clntPubKey; | 372 SECKEYPublicKey clntPubKey; |
373 CK_MECHANISM_TYPE» target; | 373 CK_MECHANISM_TYPE target; |
374 PRBool isTLS, isTLS12; | 374 PRBool isTLS, isTLS12; |
375 | 375 |
376 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 376 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
377 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 377 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
378 | 378 |
379 clntPubKey.keyType = ecKey; | 379 clntPubKey.keyType = ecKey; |
380 clntPubKey.u.ec.DEREncodedParams.len = | 380 clntPubKey.u.ec.DEREncodedParams.len = |
381 » srvrPubKey->u.ec.DEREncodedParams.len; | 381 srvrPubKey->u.ec.DEREncodedParams.len; |
382 clntPubKey.u.ec.DEREncodedParams.data = | 382 clntPubKey.u.ec.DEREncodedParams.data = |
383 » srvrPubKey->u.ec.DEREncodedParams.data; | 383 srvrPubKey->u.ec.DEREncodedParams.data; |
384 | 384 |
385 rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue, | 385 rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue, |
386 » 1, &b, &length); | 386 1, &b, &length); |
387 if (rv != SECSuccess) { | 387 if (rv != SECSuccess) { |
388 » SEND_ALERT | 388 SEND_ALERT |
389 » return SECFailure;» /* XXX Who sets the error code?? */ | 389 return SECFailure; /* XXX Who sets the error code?? */ |
390 } | 390 } |
391 | 391 |
392 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); | 392 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
393 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 393 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
394 | 394 |
395 if (isTLS12) { | 395 if (isTLS12) { |
396 » target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; | 396 target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256; |
397 } else if (isTLS) { | 397 } else if (isTLS) { |
398 » target = CKM_TLS_MASTER_KEY_DERIVE_DH; | 398 target = CKM_TLS_MASTER_KEY_DERIVE_DH; |
399 } else { | 399 } else { |
400 » target = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 400 target = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
401 } | 401 } |
402 | 402 |
403 /* Determine the PMS */ | 403 /* Determine the PMS */ |
404 pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, | 404 pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, |
405 » » » CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, | 405 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, |
406 » » » CKD_NULL, NULL, NULL); | 406 CKD_NULL, NULL, NULL); |
407 | 407 |
408 if (pms == NULL) { | 408 if (pms == NULL) { |
409 » /* last gasp. */ | 409 /* last gasp. */ |
410 » ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); | 410 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); |
411 » return SECFailure; | 411 return SECFailure; |
412 } | 412 } |
413 | 413 |
414 rv = ssl3_InitPendingCipherSpec(ss, pms); | 414 rv = ssl3_InitPendingCipherSpec(ss, pms); |
415 PK11_FreeSymKey(pms); | 415 PK11_FreeSymKey(pms); |
416 if (rv != SECSuccess) { | 416 if (rv != SECSuccess) { |
417 » SEND_ALERT | 417 SEND_ALERT |
418 » return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */ | 418 return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */ |
419 } | 419 } |
420 return SECSuccess; | 420 return SECSuccess; |
421 } | 421 } |
422 | 422 |
423 ECName | 423 ECName |
424 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits) | 424 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits) |
425 { | 425 { |
426 int i; | 426 int i; |
427 | 427 |
428 for ( i = 0; bits2curve[i].curve != ec_noName; i++) { | 428 for ( i = 0; bits2curve[i].curve != ec_noName; i++) { |
429 » if (bits2curve[i].bits < requiredECCbits) | 429 if (bits2curve[i].bits < requiredECCbits) |
430 » continue; | 430 continue; |
431 » if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) { | 431 if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) { |
432 » return bits2curve[i].curve; | 432 return bits2curve[i].curve; |
433 » } | 433 } |
434 } | 434 } |
435 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 435 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
436 return ec_noName; | 436 return ec_noName; |
437 } | 437 } |
438 | 438 |
439 /* find the "weakest link". Get strength of signature key and of sym key. | 439 /* find the "weakest link". Get strength of signature key and of sym key. |
440 * choose curve for the weakest of those two. | 440 * choose curve for the weakest of those two. |
441 */ | 441 */ |
442 ECName | 442 ECName |
443 ssl3_GetCurveNameForServerSocket(sslSocket *ss) | 443 ssl3_GetCurveNameForServerSocket(sslSocket *ss) |
444 { | 444 { |
445 SECKEYPublicKey * svrPublicKey = NULL; | 445 SECKEYPublicKey * svrPublicKey = NULL; |
446 ECName ec_curve = ec_noName; | 446 ECName ec_curve = ec_noName; |
447 int signatureKeyStrength = 521; | 447 int signatureKeyStrength = 521; |
448 int requiredECCbits = ss->sec.secretKeyBits * 2; | 448 int requiredECCbits = ss->sec.secretKeyBits * 2; |
449 | 449 |
450 if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) { | 450 if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) { |
451 » svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh); | 451 svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh); |
452 » if (svrPublicKey) | 452 if (svrPublicKey) |
453 » ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams); | 453 ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams); |
454 » if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve))
{ | 454 if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve))
{ |
455 » PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 455 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
456 » return ec_noName; | 456 return ec_noName; |
457 » } | 457 } |
458 » signatureKeyStrength = curve2bits[ ec_curve ]; | 458 signatureKeyStrength = curve2bits[ ec_curve ]; |
459 } else { | 459 } else { |
460 /* RSA is our signing cert */ | 460 /* RSA is our signing cert */ |
461 int serverKeyStrengthInBits; | 461 int serverKeyStrengthInBits; |
462 | 462 |
463 svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa); | 463 svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa); |
464 if (!svrPublicKey) { | 464 if (!svrPublicKey) { |
465 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); | 465 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
466 return ec_noName; | 466 return ec_noName; |
467 } | 467 } |
468 | 468 |
469 /* currently strength in bytes */ | 469 /* currently strength in bytes */ |
470 serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len; | 470 serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len; |
471 if (svrPublicKey->u.rsa.modulus.data[0] == 0) { | 471 if (svrPublicKey->u.rsa.modulus.data[0] == 0) { |
472 serverKeyStrengthInBits--; | 472 serverKeyStrengthInBits--; |
473 } | 473 } |
474 /* convert to strength in bits */ | 474 /* convert to strength in bits */ |
475 serverKeyStrengthInBits *= BPB; | 475 serverKeyStrengthInBits *= BPB; |
476 | 476 |
477 signatureKeyStrength = | 477 signatureKeyStrength = |
478 » SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); | 478 SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); |
479 } | 479 } |
480 if ( requiredECCbits > signatureKeyStrength ) | 480 if ( requiredECCbits > signatureKeyStrength ) |
481 requiredECCbits = signatureKeyStrength; | 481 requiredECCbits = signatureKeyStrength; |
482 | 482 |
483 return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves, | 483 return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves, |
484 » » » » » requiredECCbits); | 484 requiredECCbits); |
485 } | 485 } |
486 | 486 |
487 /* function to clear out the lists */ | 487 /* function to clear out the lists */ |
488 static SECStatus | 488 static SECStatus |
489 ssl3_ShutdownECDHECurves(void *appData, void *nssData) | 489 ssl3_ShutdownECDHECurves(void *appData, void *nssData) |
490 { | 490 { |
491 int i; | 491 int i; |
492 ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0]; | 492 ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0]; |
493 | 493 |
494 for (i=0; i < ec_pastLastName; i++, keyPair++) { | 494 for (i=0; i < ec_pastLastName; i++, keyPair++) { |
495 » if (keyPair->pair) { | 495 if (keyPair->pair) { |
496 » ssl3_FreeKeyPair(keyPair->pair); | 496 ssl3_FreeKeyPair(keyPair->pair); |
497 » } | 497 } |
498 } | 498 } |
499 memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs); | 499 memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs); |
500 return SECSuccess; | 500 return SECSuccess; |
501 } | 501 } |
502 | 502 |
503 static PRStatus | 503 static PRStatus |
504 ssl3_ECRegister(void) | 504 ssl3_ECRegister(void) |
505 { | 505 { |
506 SECStatus rv; | 506 SECStatus rv; |
507 rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs); | 507 rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs); |
508 if (rv != SECSuccess) { | 508 if (rv != SECSuccess) { |
509 » gECDHEKeyPairs[ec_noName].error = PORT_GetError(); | 509 gECDHEKeyPairs[ec_noName].error = PORT_GetError(); |
510 } | 510 } |
511 return (PRStatus)rv; | 511 return (PRStatus)rv; |
512 } | 512 } |
513 | 513 |
514 /* CallOnce function, called once for each named curve. */ | 514 /* Create an ECDHE key pair for a given curve */ |
515 static PRStatus | 515 static SECStatus |
516 ssl3_CreateECDHEphemeralKeyPair(void * arg) | 516 ssl3_CreateECDHEphemeralKeyPair(ECName ec_curve, ssl3KeyPair** keyPair) |
517 { | 517 { |
518 SECKEYPrivateKey * privKey = NULL; | 518 SECKEYPrivateKey * privKey = NULL; |
519 SECKEYPublicKey * pubKey = NULL; | 519 SECKEYPublicKey * pubKey = NULL; |
520 ssl3KeyPair *» keyPair = NULL; | 520 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; |
| 521 |
| 522 if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) { |
| 523 return SECFailure; |
| 524 } |
| 525 privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); |
| 526 SECITEM_FreeItem(&ecParams, PR_FALSE); |
| 527 |
| 528 if (!privKey || !pubKey || !(*keyPair = ssl3_NewKeyPair(privKey, pubKey))) { |
| 529 if (privKey) { |
| 530 SECKEY_DestroyPrivateKey(privKey); |
| 531 } |
| 532 if (pubKey) { |
| 533 SECKEY_DestroyPublicKey(pubKey); |
| 534 } |
| 535 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); |
| 536 return SECFailure; |
| 537 } |
| 538 |
| 539 return SECSuccess; |
| 540 } |
| 541 |
| 542 /* CallOnce function, called once for each named curve. */ |
| 543 static PRStatus |
| 544 ssl3_CreateECDHEphemeralKeyPairOnce(void * arg) |
| 545 { |
521 ECName ec_curve = (ECName)arg; | 546 ECName ec_curve = (ECName)arg; |
522 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; | 547 ssl3KeyPair * keyPair = NULL; |
523 | 548 |
524 PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); | 549 PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); |
525 | 550 |
526 /* ok, no one has generated a global key for this curve yet, do so */ | 551 /* ok, no one has generated a global key for this curve yet, do so */ |
527 if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) { | 552 if (ssl3_CreateECDHEphemeralKeyPair(ec_curve, &keyPair) != SECSuccess) { |
528 » gECDHEKeyPairs[ec_curve].error = PORT_GetError(); | 553 gECDHEKeyPairs[ec_curve].error = PORT_GetError(); |
529 » return PR_FAILURE; | 554 return PR_FAILURE; |
530 } | |
531 | |
532 privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); | |
533 SECITEM_FreeItem(&ecParams, PR_FALSE); | |
534 | |
535 if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) { | |
536 » if (privKey) { | |
537 » SECKEY_DestroyPrivateKey(privKey); | |
538 » } | |
539 » if (pubKey) { | |
540 » SECKEY_DestroyPublicKey(pubKey); | |
541 » } | |
542 » ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); | |
543 » gECDHEKeyPairs[ec_curve].error = PORT_GetError(); | |
544 » return PR_FAILURE; | |
545 } | 555 } |
546 | 556 |
547 gECDHEKeyPairs[ec_curve].pair = keyPair; | 557 gECDHEKeyPairs[ec_curve].pair = keyPair; |
548 return PR_SUCCESS; | 558 return PR_SUCCESS; |
549 } | 559 } |
550 | 560 |
551 /* | 561 /* |
552 * Creates the ephemeral public and private ECDH keys used by | 562 * Creates the ephemeral public and private ECDH keys used by |
553 * server in ECDHE_RSA and ECDHE_ECDSA handshakes. | 563 * server in ECDHE_RSA and ECDHE_ECDSA handshakes. |
554 * For now, the elliptic curve is chosen to be the same | 564 * For now, the elliptic curve is chosen to be the same |
555 * strength as the signing certificate (ECC or RSA). | 565 * strength as the signing certificate (ECC or RSA). |
556 * We need an API to specify the curve. This won't be a real | 566 * We need an API to specify the curve. This won't be a real |
557 * issue until we further develop server-side support for ECC | 567 * issue until we further develop server-side support for ECC |
558 * cipher suites. | 568 * cipher suites. |
559 */ | 569 */ |
560 static SECStatus | 570 static SECStatus |
561 ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve) | 571 ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve) |
562 { | 572 { |
563 ssl3KeyPair *» keyPair = NULL; | 573 ssl3KeyPair * keyPair = NULL; |
564 | 574 |
565 /* if there's no global key for this curve, make one. */ | 575 /* if there's no global key for this curve, make one. */ |
566 if (gECDHEKeyPairs[ec_curve].pair == NULL) { | 576 if (gECDHEKeyPairs[ec_curve].pair == NULL) { |
567 » PRStatus status; | 577 PRStatus status; |
568 | 578 |
569 » status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister); | 579 status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister); |
570 if (status != PR_SUCCESS) { | 580 if (status != PR_SUCCESS) { |
571 » PORT_SetError(gECDHEKeyPairs[ec_noName].error); | 581 PORT_SetError(gECDHEKeyPairs[ec_noName].error); |
572 » return SECFailure; | 582 return SECFailure; |
573 » } | 583 } |
574 » status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once, | 584 status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once, |
575 » ssl3_CreateECDHEphemeralKeyPair, | 585 ssl3_CreateECDHEphemeralKeyPairOnce, |
576 » » » » (void *)ec_curve); | 586 (void *)ec_curve); |
577 if (status != PR_SUCCESS) { | 587 if (status != PR_SUCCESS) { |
578 » PORT_SetError(gECDHEKeyPairs[ec_curve].error); | 588 PORT_SetError(gECDHEKeyPairs[ec_curve].error); |
579 » return SECFailure; | 589 return SECFailure; |
580 » } | 590 } |
581 } | 591 } |
582 | 592 |
583 keyPair = gECDHEKeyPairs[ec_curve].pair; | 593 keyPair = gECDHEKeyPairs[ec_curve].pair; |
584 PORT_Assert(keyPair != NULL); | 594 PORT_Assert(keyPair != NULL); |
585 if (!keyPair) | 595 if (!keyPair) |
586 » return SECFailure; | 596 return SECFailure; |
587 ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair); | 597 ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair); |
588 | 598 |
589 return SECSuccess; | 599 return SECSuccess; |
590 } | 600 } |
591 | 601 |
592 SECStatus | 602 SECStatus |
593 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) | 603 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) |
594 { | 604 { |
595 PLArenaPool * arena = NULL; | 605 PLArenaPool * arena = NULL; |
596 SECKEYPublicKey *peerKey = NULL; | 606 SECKEYPublicKey *peerKey = NULL; |
(...skipping 14 matching lines...) Expand all Loading... |
611 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); | 621 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); |
612 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 622 isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
613 | 623 |
614 /* XXX This works only for named curves, revisit this when | 624 /* XXX This works only for named curves, revisit this when |
615 * we support generic curves. | 625 * we support generic curves. |
616 */ | 626 */ |
617 ec_params.len = sizeof paramBuf; | 627 ec_params.len = sizeof paramBuf; |
618 ec_params.data = paramBuf; | 628 ec_params.data = paramBuf; |
619 rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); | 629 rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); |
620 if (rv != SECSuccess) { | 630 if (rv != SECSuccess) { |
621 » goto loser;» » /* malformed. */ | 631 goto loser; /* malformed. */ |
622 } | 632 } |
623 | 633 |
624 /* Fail if the curve is not a named curve */ | 634 /* Fail if the curve is not a named curve */ |
625 if ((ec_params.data[0] != ec_type_named) || | 635 if ((ec_params.data[0] != ec_type_named) || |
626 » (ec_params.data[1] != 0) || | 636 (ec_params.data[1] != 0) || |
627 » !supportedCurve(ec_params.data[2])) { | 637 !supportedCurve(ec_params.data[2])) { |
628 » errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; | 638 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; |
629 » desc = handshake_failure; | 639 desc = handshake_failure; |
630 » goto alert_loser; | 640 goto alert_loser; |
631 } | 641 } |
632 | 642 |
633 rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length); | 643 rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length); |
634 if (rv != SECSuccess) { | 644 if (rv != SECSuccess) { |
635 » goto loser;» » /* malformed. */ | 645 goto loser; /* malformed. */ |
636 } | 646 } |
637 /* Fail if the ec point uses compressed representation */ | 647 /* Fail if the ec point uses compressed representation */ |
638 if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) { | 648 if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) { |
639 » errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM; | 649 errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM; |
640 » desc = handshake_failure; | 650 desc = handshake_failure; |
641 » goto alert_loser; | 651 goto alert_loser; |
642 } | 652 } |
643 | 653 |
644 if (isTLS12) { | 654 if (isTLS12) { |
645 » rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, | 655 rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, |
646 » » » » » » &sigAndHash); | 656 &sigAndHash); |
647 » if (rv != SECSuccess) { | 657 if (rv != SECSuccess) { |
648 » goto loser;»» /* malformed or unsupported. */ | 658 goto loser; /* malformed or unsupported. */ |
649 » } | 659 } |
650 » rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( | 660 rv = ssl3_CheckSignatureAndHashAlgorithmConsistency( |
651 » » &sigAndHash, ss->sec.peerCert); | 661 &sigAndHash, ss->sec.peerCert); |
652 » if (rv != SECSuccess) { | 662 if (rv != SECSuccess) { |
653 » goto loser; | 663 goto loser; |
654 » } | 664 } |
655 } | 665 } |
656 | 666 |
657 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); | 667 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); |
658 if (rv != SECSuccess) { | 668 if (rv != SECSuccess) { |
659 » goto loser;» » /* malformed. */ | 669 goto loser; /* malformed. */ |
660 } | 670 } |
661 | 671 |
662 if (length != 0) { | 672 if (length != 0) { |
663 » if (isTLS) | 673 if (isTLS) |
664 » desc = decode_error; | 674 desc = decode_error; |
665 » goto alert_loser;» » /* malformed. */ | 675 goto alert_loser; /* malformed. */ |
666 } | 676 } |
667 | 677 |
668 PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, | 678 PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, |
669 » ec_params.len)); | 679 ec_params.len)); |
670 PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len)); | 680 PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len)); |
671 | 681 |
672 /* failures after this point are not malformed handshakes. */ | 682 /* failures after this point are not malformed handshakes. */ |
673 /* TLS: send decrypt_error if signature failed. */ | 683 /* TLS: send decrypt_error if signature failed. */ |
674 desc = isTLS ? decrypt_error : handshake_failure; | 684 desc = isTLS ? decrypt_error : handshake_failure; |
675 | 685 |
676 /* | 686 /* |
677 * check to make sure the hash is signed by right guy | 687 * check to make sure the hash is signed by right guy |
678 */ | 688 */ |
679 rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point, | 689 rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point, |
680 » » » » &ss->ssl3.hs.client_random, | 690 &ss->ssl3.hs.client_random, |
681 » » » » &ss->ssl3.hs.server_random, | 691 &ss->ssl3.hs.server_random, |
682 » » » » &hashes, ss->opt.bypassPKCS11); | 692 &hashes, ss->opt.bypassPKCS11); |
683 | 693 |
684 if (rv != SECSuccess) { | 694 if (rv != SECSuccess) { |
685 » errCode = | 695 errCode = |
686 » ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 696 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
687 » goto alert_loser; | 697 goto alert_loser; |
688 } | 698 } |
689 rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, | 699 rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, |
690 » » » » isTLS, ss->pkcs11PinArg); | 700 isTLS, ss->pkcs11PinArg); |
691 if (rv != SECSuccess) { | 701 if (rv != SECSuccess) { |
692 » errCode = | 702 errCode = |
693 » ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 703 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
694 » goto alert_loser; | 704 goto alert_loser; |
695 } | 705 } |
696 | 706 |
697 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 707 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
698 if (arena == NULL) { | 708 if (arena == NULL) { |
699 » goto no_memory; | 709 goto no_memory; |
700 } | 710 } |
701 | 711 |
702 ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); | 712 ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); |
703 if (peerKey == NULL) { | 713 if (peerKey == NULL) { |
704 » goto no_memory; | 714 goto no_memory; |
705 } | 715 } |
706 | 716 |
707 peerKey->arena = arena; | 717 peerKey->arena = arena; |
708 peerKey->keyType = ecKey; | 718 peerKey->keyType = ecKey; |
709 | 719 |
710 /* set up EC parameters in peerKey */ | 720 /* set up EC parameters in peerKey */ |
711 if (ssl3_ECName2Params(arena, ec_params.data[2], | 721 if (ssl3_ECName2Params(arena, ec_params.data[2], |
712 » &peerKey->u.ec.DEREncodedParams) != SECSuccess) { | 722 &peerKey->u.ec.DEREncodedParams) != SECSuccess) { |
713 » /* we should never get here since we already | 723 /* we should never get here since we already |
714 » * checked that we are dealing with a supported curve | 724 * checked that we are dealing with a supported curve |
715 » */ | 725 */ |
716 » errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; | 726 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; |
717 » goto alert_loser; | 727 goto alert_loser; |
718 } | 728 } |
719 | 729 |
720 /* copy publicValue in peerKey */ | 730 /* copy publicValue in peerKey */ |
721 if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point)) | 731 if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point)) |
722 { | 732 { |
723 » PORT_FreeArena(arena, PR_FALSE); | 733 PORT_FreeArena(arena, PR_FALSE); |
724 » goto no_memory; | 734 goto no_memory; |
725 } | 735 } |
726 peerKey->pkcs11Slot = NULL; | 736 peerKey->pkcs11Slot = NULL; |
727 peerKey->pkcs11ID = CK_INVALID_HANDLE; | 737 peerKey->pkcs11ID = CK_INVALID_HANDLE; |
728 | 738 |
729 ss->sec.peerKey = peerKey; | 739 ss->sec.peerKey = peerKey; |
730 ss->ssl3.hs.ws = wait_cert_request; | 740 ss->ssl3.hs.ws = wait_cert_request; |
731 | 741 |
732 return SECSuccess; | 742 return SECSuccess; |
733 | 743 |
734 alert_loser: | 744 alert_loser: |
735 (void)SSL3_SendAlert(ss, alert_fatal, desc); | 745 (void)SSL3_SendAlert(ss, alert_fatal, desc); |
736 loser: | 746 loser: |
737 PORT_SetError( errCode ); | 747 PORT_SetError( errCode ); |
738 return SECFailure; | 748 return SECFailure; |
739 | 749 |
740 no_memory:» /* no-memory error has already been set. */ | 750 no_memory: /* no-memory error has already been set. */ |
741 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 751 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
742 return SECFailure; | 752 return SECFailure; |
743 } | 753 } |
744 | 754 |
745 SECStatus | 755 SECStatus |
746 ssl3_SendECDHServerKeyExchange( | 756 ssl3_SendECDHServerKeyExchange( |
747 sslSocket *ss, | 757 sslSocket *ss, |
748 const SSL3SignatureAndHashAlgorithm *sigAndHash) | 758 const SSL3SignatureAndHashAlgorithm *sigAndHash) |
749 { | 759 { |
750 const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; | 760 const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; |
751 SECStatus rv = SECFailure; | 761 SECStatus rv = SECFailure; |
752 int length; | 762 int length; |
753 PRBool isTLS, isTLS12; | 763 PRBool isTLS, isTLS12; |
754 SECItem signed_hash = {siBuffer, NULL, 0}; | 764 SECItem signed_hash = {siBuffer, NULL, 0}; |
755 SSL3Hashes hashes; | 765 SSL3Hashes hashes; |
756 | 766 |
757 SECKEYPublicKey * ecdhePub; | 767 SECKEYPublicKey * ecdhePub; |
758 SECItem ec_params = {siBuffer, NULL, 0}; | 768 SECItem ec_params = {siBuffer, NULL, 0}; |
759 unsigned char paramBuf[3]; | 769 unsigned char paramBuf[3]; |
760 ECName curve; | 770 ECName curve; |
761 SSL3KEAType certIndex; | 771 SSL3KEAType certIndex; |
762 | 772 |
763 /* Generate ephemeral ECDH key pair and send the public key */ | 773 /* Generate ephemeral ECDH key pair and send the public key */ |
764 curve = ssl3_GetCurveNameForServerSocket(ss); | 774 curve = ssl3_GetCurveNameForServerSocket(ss); |
765 if (curve == ec_noName) { | 775 if (curve == ec_noName) { |
766 » goto loser; | 776 goto loser; |
767 } | 777 } |
768 rv = ssl3_CreateECDHEphemeralKeys(ss, curve); | 778 |
| 779 if (ss->opt.reuseServerECDHEKey) { |
| 780 rv = ssl3_CreateECDHEphemeralKeys(ss, curve); |
| 781 } else { |
| 782 rv = ssl3_CreateECDHEphemeralKeyPair(curve, &ss->ephemeralECDHKeyPair); |
| 783 } |
769 if (rv != SECSuccess) { | 784 if (rv != SECSuccess) { |
770 » goto loser; » /* err set by AppendHandshake. */ | 785 goto loser; |
771 }» | 786 } |
| 787 |
772 ecdhePub = ss->ephemeralECDHKeyPair->pubKey; | 788 ecdhePub = ss->ephemeralECDHKeyPair->pubKey; |
773 PORT_Assert(ecdhePub != NULL); | 789 PORT_Assert(ecdhePub != NULL); |
774 if (!ecdhePub) { | 790 if (!ecdhePub) { |
775 » PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 791 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
776 » return SECFailure; | 792 return SECFailure; |
777 }» | 793 } |
778 | 794 |
779 ec_params.len = sizeof paramBuf; | 795 ec_params.len = sizeof paramBuf; |
780 ec_params.data = paramBuf; | 796 ec_params.data = paramBuf; |
781 curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams); | 797 curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams); |
782 if (curve != ec_noName) { | 798 if (curve != ec_noName) { |
783 » ec_params.data[0] = ec_type_named; | 799 ec_params.data[0] = ec_type_named; |
784 » ec_params.data[1] = 0x00; | 800 ec_params.data[1] = 0x00; |
785 » ec_params.data[2] = curve; | 801 ec_params.data[2] = curve; |
786 } else { | 802 } else { |
787 » PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 803 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); |
788 » goto loser; | 804 goto loser; |
789 }» » | 805 } |
790 | 806 |
791 rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg, | 807 rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg, |
792 » » » » ec_params, | 808 ec_params, |
793 » » » » ecdhePub->u.ec.publicValue, | 809 ecdhePub->u.ec.publicValue, |
794 » » » » &ss->ssl3.hs.client_random, | 810 &ss->ssl3.hs.client_random, |
795 » » » » &ss->ssl3.hs.server_random, | 811 &ss->ssl3.hs.server_random, |
796 » » » » &hashes, ss->opt.bypassPKCS11); | 812 &hashes, ss->opt.bypassPKCS11); |
797 if (rv != SECSuccess) { | 813 if (rv != SECSuccess) { |
798 » ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 814 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
799 » goto loser; | 815 goto loser; |
800 } | 816 } |
801 | 817 |
802 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); | 818 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
803 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); | 819 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); |
804 | 820 |
805 /* XXX SSLKEAType isn't really a good choice for | 821 /* XXX SSLKEAType isn't really a good choice for |
806 * indexing certificates but that's all we have | 822 * indexing certificates but that's all we have |
807 * for now. | 823 * for now. |
808 */ | 824 */ |
809 if (kea_def->kea == kea_ecdhe_rsa) | 825 if (kea_def->kea == kea_ecdhe_rsa) |
810 » certIndex = kt_rsa; | 826 certIndex = kt_rsa; |
811 else /* kea_def->kea == kea_ecdhe_ecdsa */ | 827 else /* kea_def->kea == kea_ecdhe_ecdsa */ |
812 » certIndex = kt_ecdh; | 828 certIndex = kt_ecdh; |
813 | 829 |
814 rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY, | 830 rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY, |
815 » » » &signed_hash, isTLS); | 831 &signed_hash, isTLS); |
816 if (rv != SECSuccess) { | 832 if (rv != SECSuccess) { |
817 » goto loser;» » /* ssl3_SignHashes has set err. */ | 833 goto loser; /* ssl3_SignHashes has set err. */ |
818 } | 834 } |
819 if (signed_hash.data == NULL) { | 835 if (signed_hash.data == NULL) { |
820 » /* how can this happen and rv == SECSuccess ?? */ | 836 /* how can this happen and rv == SECSuccess ?? */ |
821 » PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); | 837 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); |
822 » goto loser; | 838 goto loser; |
823 } | 839 } |
824 | 840 |
825 length = ec_params.len + | 841 length = ec_params.len + |
826 » 1 + ecdhePub->u.ec.publicValue.len + | 842 1 + ecdhePub->u.ec.publicValue.len + |
827 » (isTLS12 ? 2 : 0) + 2 + signed_hash.len; | 843 (isTLS12 ? 2 : 0) + 2 + signed_hash.len; |
828 | 844 |
829 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); | 845 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); |
830 if (rv != SECSuccess) { | 846 if (rv != SECSuccess) { |
831 » goto loser; » /* err set by AppendHandshake. */ | 847 goto loser; /* err set by AppendHandshake. */ |
832 } | 848 } |
833 | 849 |
834 rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len); | 850 rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len); |
835 if (rv != SECSuccess) { | 851 if (rv != SECSuccess) { |
836 » goto loser; » /* err set by AppendHandshake. */ | 852 goto loser; /* err set by AppendHandshake. */ |
837 } | 853 } |
838 | 854 |
839 rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data, | 855 rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data, |
840 » » » » ecdhePub->u.ec.publicValue.len, 1); | 856 ecdhePub->u.ec.publicValue.len, 1); |
841 if (rv != SECSuccess) { | 857 if (rv != SECSuccess) { |
842 » goto loser; » /* err set by AppendHandshake. */ | 858 goto loser; /* err set by AppendHandshake. */ |
843 } | 859 } |
844 | 860 |
845 if (isTLS12) { | 861 if (isTLS12) { |
846 » rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash); | 862 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash); |
847 » if (rv != SECSuccess) { | 863 if (rv != SECSuccess) { |
848 » goto loser; » /* err set by AppendHandshake. */ | 864 goto loser; /* err set by AppendHandshake. */ |
849 » } | 865 } |
850 } | 866 } |
851 | 867 |
852 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, | 868 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data, |
853 » » » » signed_hash.len, 2); | 869 signed_hash.len, 2); |
854 if (rv != SECSuccess) { | 870 if (rv != SECSuccess) { |
855 » goto loser; » /* err set by AppendHandshake. */ | 871 goto loser; /* err set by AppendHandshake. */ |
856 } | 872 } |
857 | 873 |
858 PORT_Free(signed_hash.data); | 874 PORT_Free(signed_hash.data); |
859 return SECSuccess; | 875 return SECSuccess; |
860 | 876 |
861 loser: | 877 loser: |
862 if (signed_hash.data != NULL) | 878 if (signed_hash.data != NULL) |
863 » PORT_Free(signed_hash.data); | 879 PORT_Free(signed_hash.data); |
864 return SECFailure; | 880 return SECFailure; |
865 } | 881 } |
866 | 882 |
867 /* Lists of ECC cipher suites for searching and disabling. */ | 883 /* Lists of ECC cipher suites for searching and disabling. */ |
868 | 884 |
869 static const ssl3CipherSuite ecdh_suites[] = { | 885 static const ssl3CipherSuite ecdh_suites[] = { |
870 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | 886 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, |
871 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, | 887 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, |
872 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, | 888 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, |
873 TLS_ECDH_ECDSA_WITH_NULL_SHA, | 889 TLS_ECDH_ECDSA_WITH_NULL_SHA, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 TLS_ECDH_RSA_WITH_NULL_SHA, | 967 TLS_ECDH_RSA_WITH_NULL_SHA, |
952 TLS_ECDH_RSA_WITH_RC4_128_SHA, | 968 TLS_ECDH_RSA_WITH_RC4_128_SHA, |
953 0 /* end of list marker */ | 969 0 /* end of list marker */ |
954 }; | 970 }; |
955 | 971 |
956 /* On this socket, Disable the ECC cipher suites in the argument's list */ | 972 /* On this socket, Disable the ECC cipher suites in the argument's list */ |
957 SECStatus | 973 SECStatus |
958 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite) | 974 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite) |
959 { | 975 { |
960 if (!suite) | 976 if (!suite) |
961 » suite = ecSuites; | 977 suite = ecSuites; |
962 for (; *suite; ++suite) { | 978 for (; *suite; ++suite) { |
963 » SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE); | 979 SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE); |
964 | 980 |
965 » PORT_Assert(rv == SECSuccess); /* else is coding error */ | 981 PORT_Assert(rv == SECSuccess); /* else is coding error */ |
966 } | 982 } |
967 return SECSuccess; | 983 return SECSuccess; |
968 } | 984 } |
969 | 985 |
970 /* Look at the server certs configured on this socket, and disable any | 986 /* Look at the server certs configured on this socket, and disable any |
971 * ECC cipher suites that are not supported by those certs. | 987 * ECC cipher suites that are not supported by those certs. |
972 */ | 988 */ |
973 void | 989 void |
974 ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss) | 990 ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss) |
975 { | 991 { |
976 CERTCertificate * svrCert; | 992 CERTCertificate * svrCert; |
977 | 993 |
978 svrCert = ss->serverCerts[kt_rsa].serverCert; | 994 svrCert = ss->serverCerts[kt_rsa].serverCert; |
979 if (!svrCert) { | 995 if (!svrCert) { |
980 » ssl3_DisableECCSuites(ss, ecdhe_rsa_suites); | 996 ssl3_DisableECCSuites(ss, ecdhe_rsa_suites); |
981 } | 997 } |
982 | 998 |
983 svrCert = ss->serverCerts[kt_ecdh].serverCert; | 999 svrCert = ss->serverCerts[kt_ecdh].serverCert; |
984 if (!svrCert) { | 1000 if (!svrCert) { |
985 » ssl3_DisableECCSuites(ss, ecdh_suites); | 1001 ssl3_DisableECCSuites(ss, ecdh_suites); |
986 » ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); | 1002 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); |
987 } else { | 1003 } else { |
988 » SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature); | 1004 SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature); |
989 | 1005 |
990 » switch (sigTag) { | 1006 switch (sigTag) { |
991 » case SEC_OID_PKCS1_RSA_ENCRYPTION: | 1007 case SEC_OID_PKCS1_RSA_ENCRYPTION: |
992 » case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: | 1008 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: |
993 » case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: | 1009 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: |
994 » case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: | 1010 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: |
995 » case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: | 1011 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: |
996 » case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: | 1012 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: |
997 » case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: | 1013 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: |
998 » case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: | 1014 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: |
999 » case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: | 1015 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: |
1000 » ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); | 1016 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); |
1001 » break; | 1017 break; |
1002 » case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: | 1018 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: |
1003 » case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: | 1019 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: |
1004 » case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: | 1020 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: |
1005 » case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: | 1021 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: |
1006 » case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: | 1022 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: |
1007 » case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: | 1023 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: |
1008 » case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: | 1024 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: |
1009 » ssl3_DisableECCSuites(ss, ecdh_rsa_suites); | 1025 ssl3_DisableECCSuites(ss, ecdh_rsa_suites); |
1010 » break; | 1026 break; |
1011 » default: | 1027 default: |
1012 » ssl3_DisableECCSuites(ss, ecdh_suites); | 1028 ssl3_DisableECCSuites(ss, ecdh_suites); |
1013 » break; | 1029 break; |
1014 » } | 1030 } |
1015 } | 1031 } |
1016 } | 1032 } |
1017 | 1033 |
1018 /* Ask: is ANY ECC cipher suite enabled on this socket? */ | 1034 /* Ask: is ANY ECC cipher suite enabled on this socket? */ |
1019 /* Order(N^2). Yuk. Also, this ignores export policy. */ | 1035 /* Order(N^2). Yuk. Also, this ignores export policy. */ |
1020 PRBool | 1036 PRBool |
1021 ssl3_IsECCEnabled(sslSocket * ss) | 1037 ssl3_IsECCEnabled(sslSocket * ss) |
1022 { | 1038 { |
1023 const ssl3CipherSuite * suite; | 1039 const ssl3CipherSuite * suite; |
1024 PK11SlotInfo *slot; | 1040 PK11SlotInfo *slot; |
1025 | 1041 |
1026 /* make sure we can do ECC */ | 1042 /* make sure we can do ECC */ |
1027 slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg); | 1043 slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg); |
1028 if (!slot) { | 1044 if (!slot) { |
1029 » return PR_FALSE; | 1045 return PR_FALSE; |
1030 } | 1046 } |
1031 PK11_FreeSlot(slot); | 1047 PK11_FreeSlot(slot); |
1032 | 1048 |
1033 /* make sure an ECC cipher is enabled */ | 1049 /* make sure an ECC cipher is enabled */ |
1034 for (suite = ecSuites; *suite; ++suite) { | 1050 for (suite = ecSuites; *suite; ++suite) { |
1035 » PRBool enabled = PR_FALSE; | 1051 PRBool enabled = PR_FALSE; |
1036 » SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled); | 1052 SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled); |
1037 | 1053 |
1038 » PORT_Assert(rv == SECSuccess); /* else is coding error */ | 1054 PORT_Assert(rv == SECSuccess); /* else is coding error */ |
1039 » if (rv == SECSuccess && enabled) | 1055 if (rv == SECSuccess && enabled) |
1040 » return PR_TRUE; | 1056 return PR_TRUE; |
1041 } | 1057 } |
1042 return PR_FALSE; | 1058 return PR_FALSE; |
1043 } | 1059 } |
1044 | 1060 |
1045 #define BE(n) 0, n | 1061 #define BE(n) 0, n |
1046 | 1062 |
1047 /* Prefabricated TLS client hello extension, Elliptic Curves List, | 1063 /* Prefabricated TLS client hello extension, Elliptic Curves List, |
1048 * offers only 3 curves, the Suite B curves, 23-25 | 1064 * offers only 3 curves, the Suite B curves, 23-25 |
1049 */ | 1065 */ |
1050 static const PRUint8 suiteBECList[12] = { | 1066 static const PRUint8 suiteBECList[12] = { |
1051 BE(10), /* Extension type */ | 1067 BE(10), /* Extension type */ |
1052 BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */ | 1068 BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */ |
1053 BE( 6), /* octets that follow ( 3 pairs) */ | 1069 BE( 6), /* octets that follow ( 3 pairs) */ |
1054 BE(23), BE(24), BE(25) | 1070 BE(23), BE(24), BE(25) |
1055 }; | 1071 }; |
1056 | 1072 |
1057 /* Prefabricated TLS client hello extension, Elliptic Curves List, | 1073 /* Prefabricated TLS client hello extension, Elliptic Curves List, |
1058 * offers curves 1-25. | 1074 * offers curves 1-25. |
1059 */ | 1075 */ |
1060 static const PRUint8 tlsECList[56] = { | 1076 static const PRUint8 tlsECList[56] = { |
1061 BE(10), /* Extension type */ | 1077 BE(10), /* Extension type */ |
1062 BE(52), /* octets that follow (25 pairs + 1 length pair) */ | 1078 BE(52), /* octets that follow (25 pairs + 1 length pair) */ |
1063 BE(50), /* octets that follow (25 pairs) */ | 1079 BE(50), /* octets that follow (25 pairs) */ |
1064 BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7), | 1080 BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7), |
1065 BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15), | 1081 BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15), |
1066 BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23), | 1082 BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23), |
1067 BE(24), BE(25) | 1083 BE(24), BE(25) |
1068 }; | 1084 }; |
1069 | 1085 |
1070 static const PRUint8 ecPtFmt[6] = { | 1086 static const PRUint8 ecPtFmt[6] = { |
1071 BE(11), /* Extension type */ | 1087 BE(11), /* Extension type */ |
1072 BE( 2), /* octets that follow */ | 1088 BE( 2), /* octets that follow */ |
1073 1, /* octets that follow */ | 1089 1, /* octets that follow */ |
1074 0 /* uncompressed type only */ | 1090 0 /* uncompressed type only */ |
1075 }; | 1091 }; |
1076 | 1092 |
1077 /* This function already presumes we can do ECC, ssl3_IsECCEnabled must be | 1093 /* This function already presumes we can do ECC, ssl3_IsECCEnabled must be |
1078 * called before this function. It looks to see if we have a token which | 1094 * called before this function. It looks to see if we have a token which |
1079 * is capable of doing smaller than SuiteB curves. If the token can, we | 1095 * is capable of doing smaller than SuiteB curves. If the token can, we |
1080 * presume the token can do the whole SSL suite of curves. If it can't we | 1096 * presume the token can do the whole SSL suite of curves. If it can't we |
1081 * presume the token that allowed ECC to be enabled can only do suite B | 1097 * presume the token that allowed ECC to be enabled can only do suite B |
1082 * curves. */ | 1098 * curves. */ |
1083 static PRBool | 1099 static PRBool |
1084 ssl3_SuiteBOnly(sslSocket *ss) | 1100 ssl3_SuiteBOnly(sslSocket *ss) |
1085 { | 1101 { |
1086 #if 0 | 1102 #if 0 |
1087 /* See if we can support small curves (like 163). If not, assume we can | 1103 /* See if we can support small curves (like 163). If not, assume we can |
1088 * only support Suite-B curves (P-256, P-384, P-521). */ | 1104 * only support Suite-B curves (P-256, P-384, P-521). */ |
1089 PK11SlotInfo *slot = | 1105 PK11SlotInfo *slot = |
1090 » PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163, | 1106 PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163, |
1091 » » » » ss ? ss->pkcs11PinArg : NULL); | 1107 ss ? ss->pkcs11PinArg : NULL); |
1092 | 1108 |
1093 if (!slot) { | 1109 if (!slot) { |
1094 » /* nope, presume we can only do suite B */ | 1110 /* nope, presume we can only do suite B */ |
1095 » return PR_TRUE; | 1111 return PR_TRUE; |
1096 } | 1112 } |
1097 /* we can, presume we can do all curves */ | 1113 /* we can, presume we can do all curves */ |
1098 PK11_FreeSlot(slot); | 1114 PK11_FreeSlot(slot); |
1099 return PR_FALSE; | 1115 return PR_FALSE; |
1100 #else | 1116 #else |
1101 return PR_TRUE; | 1117 return PR_TRUE; |
1102 #endif | 1118 #endif |
1103 } | 1119 } |
1104 | 1120 |
1105 /* Send our "canned" (precompiled) Supported Elliptic Curves extension, | 1121 /* Send our "canned" (precompiled) Supported Elliptic Curves extension, |
1106 * which says that we support all TLS-defined named curves. | 1122 * which says that we support all TLS-defined named curves. |
1107 */ | 1123 */ |
1108 PRInt32 | 1124 PRInt32 |
1109 ssl3_SendSupportedCurvesXtn( | 1125 ssl3_SendSupportedCurvesXtn( |
1110 » » » sslSocket * ss, | 1126 sslSocket * ss, |
1111 » » » PRBool append, | 1127 PRBool append, |
1112 » » » PRUint32 maxBytes) | 1128 PRUint32 maxBytes) |
1113 { | 1129 { |
1114 PRInt32 ecListSize = 0; | 1130 PRInt32 ecListSize = 0; |
1115 const PRUint8 *ecList = NULL; | 1131 const PRUint8 *ecList = NULL; |
1116 | 1132 |
1117 if (!ss || !ssl3_IsECCEnabled(ss)) | 1133 if (!ss || !ssl3_IsECCEnabled(ss)) |
1118 » return 0; | 1134 return 0; |
1119 | 1135 |
1120 if (ssl3_SuiteBOnly(ss)) { | 1136 if (ssl3_SuiteBOnly(ss)) { |
1121 » ecListSize = sizeof suiteBECList; | 1137 ecListSize = sizeof suiteBECList; |
1122 » ecList = suiteBECList; | 1138 ecList = suiteBECList; |
1123 } else { | 1139 } else { |
1124 » ecListSize = sizeof tlsECList; | 1140 ecListSize = sizeof tlsECList; |
1125 » ecList = tlsECList; | 1141 ecList = tlsECList; |
1126 } | 1142 } |
1127 | 1143 |
1128 if (append && maxBytes >= ecListSize) { | 1144 if (append && maxBytes >= ecListSize) { |
1129 » SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize); | 1145 SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize); |
1130 » if (rv != SECSuccess) | 1146 if (rv != SECSuccess) |
1131 » return -1; | 1147 return -1; |
1132 » if (!ss->sec.isServer) { | 1148 if (!ss->sec.isServer) { |
1133 » TLSExtensionData *xtnData = &ss->xtnData; | 1149 TLSExtensionData *xtnData = &ss->xtnData; |
1134 » xtnData->advertised[xtnData->numAdvertised++] = | 1150 xtnData->advertised[xtnData->numAdvertised++] = |
1135 » » ssl_elliptic_curves_xtn; | 1151 ssl_elliptic_curves_xtn; |
1136 » } | 1152 } |
1137 } | 1153 } |
1138 return ecListSize; | 1154 return ecListSize; |
1139 } | 1155 } |
1140 | 1156 |
1141 PRUint32 | 1157 PRUint32 |
1142 ssl3_GetSupportedECCurveMask(sslSocket *ss) | 1158 ssl3_GetSupportedECCurveMask(sslSocket *ss) |
1143 { | 1159 { |
1144 if (ssl3_SuiteBOnly(ss)) { | 1160 if (ssl3_SuiteBOnly(ss)) { |
1145 » return SSL3_SUITE_B_SUPPORTED_CURVES_MASK; | 1161 return SSL3_SUITE_B_SUPPORTED_CURVES_MASK; |
1146 } | 1162 } |
1147 return SSL3_ALL_SUPPORTED_CURVES_MASK; | 1163 return SSL3_ALL_SUPPORTED_CURVES_MASK; |
1148 } | 1164 } |
1149 | 1165 |
1150 /* Send our "canned" (precompiled) Supported Point Formats extension, | 1166 /* Send our "canned" (precompiled) Supported Point Formats extension, |
1151 * which says that we only support uncompressed points. | 1167 * which says that we only support uncompressed points. |
1152 */ | 1168 */ |
1153 PRInt32 | 1169 PRInt32 |
1154 ssl3_SendSupportedPointFormatsXtn( | 1170 ssl3_SendSupportedPointFormatsXtn( |
1155 » » » sslSocket * ss, | 1171 sslSocket * ss, |
1156 » » » PRBool append, | 1172 PRBool append, |
1157 » » » PRUint32 maxBytes) | 1173 PRUint32 maxBytes) |
1158 { | 1174 { |
1159 if (!ss || !ssl3_IsECCEnabled(ss)) | 1175 if (!ss || !ssl3_IsECCEnabled(ss)) |
1160 » return 0; | 1176 return 0; |
1161 if (append && maxBytes >= (sizeof ecPtFmt)) { | 1177 if (append && maxBytes >= (sizeof ecPtFmt)) { |
1162 » SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); | 1178 SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); |
1163 » if (rv != SECSuccess) | 1179 if (rv != SECSuccess) |
1164 » return -1; | 1180 return -1; |
1165 » if (!ss->sec.isServer) { | 1181 if (!ss->sec.isServer) { |
1166 » TLSExtensionData *xtnData = &ss->xtnData; | 1182 TLSExtensionData *xtnData = &ss->xtnData; |
1167 » xtnData->advertised[xtnData->numAdvertised++] = | 1183 xtnData->advertised[xtnData->numAdvertised++] = |
1168 » » ssl_ec_point_formats_xtn; | 1184 ssl_ec_point_formats_xtn; |
1169 » } | 1185 } |
1170 } | 1186 } |
1171 return (sizeof ecPtFmt); | 1187 return (sizeof ecPtFmt); |
1172 } | 1188 } |
1173 | 1189 |
1174 /* Just make sure that the remote client supports uncompressed points, | 1190 /* Just make sure that the remote client supports uncompressed points, |
1175 * Since that is all we support. Disable ECC cipher suites if it doesn't. | 1191 * Since that is all we support. Disable ECC cipher suites if it doesn't. |
1176 */ | 1192 */ |
1177 SECStatus | 1193 SECStatus |
1178 ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type, | 1194 ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type, |
1179 SECItem *data) | 1195 SECItem *data) |
1180 { | 1196 { |
1181 int i; | 1197 int i; |
1182 | 1198 |
1183 if (data->len < 2 || data->len > 255 || !data->data || | 1199 if (data->len < 2 || data->len > 255 || !data->data || |
1184 data->len != (unsigned int)data->data[0] + 1) { | 1200 data->len != (unsigned int)data->data[0] + 1) { |
1185 » /* malformed */ | 1201 /* malformed */ |
1186 » goto loser; | 1202 goto loser; |
1187 } | 1203 } |
1188 for (i = data->len; --i > 0; ) { | 1204 for (i = data->len; --i > 0; ) { |
1189 » if (data->data[i] == 0) { | 1205 if (data->data[i] == 0) { |
1190 » /* indicate that we should send a reply */ | 1206 /* indicate that we should send a reply */ |
1191 » SECStatus rv; | 1207 SECStatus rv; |
1192 » rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, | 1208 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, |
1193 » » » &ssl3_SendSupportedPointFormatsXtn); | 1209 &ssl3_SendSupportedPointFormatsXtn); |
1194 » return rv; | 1210 return rv; |
1195 » } | 1211 } |
1196 } | 1212 } |
1197 loser: | 1213 loser: |
1198 /* evil client doesn't support uncompressed */ | 1214 /* evil client doesn't support uncompressed */ |
1199 ssl3_DisableECCSuites(ss, ecSuites); | 1215 ssl3_DisableECCSuites(ss, ecSuites); |
1200 return SECFailure; | 1216 return SECFailure; |
1201 } | 1217 } |
1202 | 1218 |
1203 | 1219 |
1204 #define SSL3_GET_SERVER_PUBLICKEY(sock, type) \ | 1220 #define SSL3_GET_SERVER_PUBLICKEY(sock, type) \ |
1205 (ss->serverCerts[type].serverKeyPair ? \ | 1221 (ss->serverCerts[type].serverKeyPair ? \ |
1206 ss->serverCerts[type].serverKeyPair->pubKey : NULL) | 1222 ss->serverCerts[type].serverKeyPair->pubKey : NULL) |
1207 | 1223 |
1208 /* Extract the TLS curve name for the public key in our EC server cert. */ | 1224 /* Extract the TLS curve name for the public key in our EC server cert. */ |
1209 ECName ssl3_GetSvrCertCurveName(sslSocket *ss) | 1225 ECName ssl3_GetSvrCertCurveName(sslSocket *ss) |
1210 { | 1226 { |
1211 SECKEYPublicKey *srvPublicKey; | 1227 SECKEYPublicKey *srvPublicKey; |
1212 ECName» » ec_curve = ec_noName; | 1228 ECName ec_curve = ec_noName; |
1213 | 1229 |
1214 srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh); | 1230 srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh); |
1215 if (srvPublicKey) { | 1231 if (srvPublicKey) { |
1216 » ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams); | 1232 ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams); |
1217 } | 1233 } |
1218 return ec_curve; | 1234 return ec_curve; |
1219 } | 1235 } |
1220 | 1236 |
1221 /* Ensure that the curve in our server cert is one of the ones suppored | 1237 /* Ensure that the curve in our server cert is one of the ones suppored |
1222 * by the remote client, and disable all ECC cipher suites if not. | 1238 * by the remote client, and disable all ECC cipher suites if not. |
1223 */ | 1239 */ |
1224 SECStatus | 1240 SECStatus |
1225 ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) | 1241 ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) |
1226 { | 1242 { |
1227 PRInt32 list_len; | 1243 PRInt32 list_len; |
1228 PRUint32 peerCurves = 0; | 1244 PRUint32 peerCurves = 0; |
1229 PRUint32 mutualCurves = 0; | 1245 PRUint32 mutualCurves = 0; |
1230 PRUint16 svrCertCurveName; | 1246 PRUint16 svrCertCurveName; |
1231 | 1247 |
1232 if (!data->data || data->len < 4 || data->len > 65535) | 1248 if (!data->data || data->len < 4 || data->len > 65535) |
1233 » goto loser; | 1249 goto loser; |
1234 /* get the length of elliptic_curve_list */ | 1250 /* get the length of elliptic_curve_list */ |
1235 list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); | 1251 list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); |
1236 if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { | 1252 if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { |
1237 » /* malformed */ | 1253 /* malformed */ |
1238 » goto loser; | 1254 goto loser; |
1239 } | 1255 } |
1240 /* build bit vector of peer's supported curve names */ | 1256 /* build bit vector of peer's supported curve names */ |
1241 while (data->len) { | 1257 while (data->len) { |
1242 » PRInt32 curve_name = | 1258 PRInt32 curve_name = |
1243 » » ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); | 1259 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); |
1244 » if (curve_name > ec_noName && curve_name < ec_pastLastName) { | 1260 if (curve_name > ec_noName && curve_name < ec_pastLastName) { |
1245 » peerCurves |= (1U << curve_name); | 1261 peerCurves |= (1U << curve_name); |
1246 » } | 1262 } |
1247 } | 1263 } |
1248 /* What curves do we support in common? */ | 1264 /* What curves do we support in common? */ |
1249 mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves; | 1265 mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves; |
1250 if (!mutualCurves) { /* no mutually supported EC Curves */ | 1266 if (!mutualCurves) { /* no mutually supported EC Curves */ |
1251 » goto loser; | 1267 goto loser; |
1252 } | 1268 } |
1253 | 1269 |
1254 /* if our ECC cert doesn't use one of these supported curves, | 1270 /* if our ECC cert doesn't use one of these supported curves, |
1255 * disable ECC cipher suites that require an ECC cert. | 1271 * disable ECC cipher suites that require an ECC cert. |
1256 */ | 1272 */ |
1257 svrCertCurveName = ssl3_GetSvrCertCurveName(ss); | 1273 svrCertCurveName = ssl3_GetSvrCertCurveName(ss); |
1258 if (svrCertCurveName != ec_noName && | 1274 if (svrCertCurveName != ec_noName && |
1259 (mutualCurves & (1U << svrCertCurveName)) != 0) { | 1275 (mutualCurves & (1U << svrCertCurveName)) != 0) { |
1260 » return SECSuccess; | 1276 return SECSuccess; |
1261 } | 1277 } |
1262 /* Our EC cert doesn't contain a mutually supported curve. | 1278 /* Our EC cert doesn't contain a mutually supported curve. |
1263 * Disable all ECC cipher suites that require an EC cert | 1279 * Disable all ECC cipher suites that require an EC cert |
1264 */ | 1280 */ |
1265 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); | 1281 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); |
1266 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); | 1282 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); |
1267 return SECFailure; | 1283 return SECFailure; |
1268 | 1284 |
1269 loser: | 1285 loser: |
1270 /* no common curve supported */ | 1286 /* no common curve supported */ |
1271 ssl3_DisableECCSuites(ss, ecSuites); | 1287 ssl3_DisableECCSuites(ss, ecSuites); |
1272 return SECFailure; | 1288 return SECFailure; |
1273 } | 1289 } |
1274 | 1290 |
1275 #endif /* NSS_ENABLE_ECC */ | 1291 #endif /* NSS_DISABLE_ECC */ |
OLD | NEW |