| 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 |