|
@@ -175,6 +175,8 @@
|
|
|
#define NID_brainpoolP256r1 927
|
|
|
#define NID_brainpoolP384r1 931
|
|
|
#define NID_brainpoolP512r1 933
|
|
|
+#define NID_X25519 1034
|
|
|
+
|
|
|
|
|
|
static int nid_list[] = {
|
|
|
NID_sect163k1,
|
|
@@ -206,12 +208,14 @@ static int nid_list[] = {
|
|
|
NID_brainpoolP384r1,
|
|
|
#if OPENSSL_VERSION_NUMBER >= 0x1010000eL
|
|
|
NID_brainpoolP512r1,
|
|
|
- NID_X25519,
|
|
|
+ NID_X25519
|
|
|
#else
|
|
|
NID_brainpoolP512r1
|
|
|
#endif
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
|
|
|
* including the ClientKeyExchange. This hash is eventually used
|
|
|
* to compute the TLS extended master secret.
|
|
@@ -330,71 +334,82 @@ int extract_parameters(flow *f, uint8_t *hs){
|
|
|
int curve_nid = 0;
|
|
|
int encoded_pt_len = 0;
|
|
|
|
|
|
- if((ecdh = EC_KEY_new()) == NULL) {
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
if(p[0] != 0x03){
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
|
|
|
int curve_id = *(p+2);
|
|
|
- printf("using curve number %d\n", curve_id);
|
|
|
+ printf("Using curve number %d\n", curve_id);
|
|
|
if((curve_id < 0) || ((unsigned int)curve_id >
|
|
|
sizeof(nid_list) / sizeof(nid_list[0]))){
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
curve_nid = nid_list[curve_id-1];
|
|
|
-
|
|
|
-
|
|
|
- if(!tls1_check_curve(s, p, 3)) {
|
|
|
- goto err;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if((*(p+2) < 1) || ((unsigned int) (*(p+2)) > sizeof(nid_list) / sizeof(nid_list[0]))){
|
|
|
-
|
|
|
- goto err;
|
|
|
- }
|
|
|
- curve_nid = nid_list[*(p+2)];
|
|
|
- */
|
|
|
-
|
|
|
- ngroup = EC_GROUP_new_by_curve_name(curve_nid);
|
|
|
-
|
|
|
- if(ngroup == NULL){
|
|
|
- goto err;
|
|
|
- }
|
|
|
- if(EC_KEY_set_group(ecdh, ngroup) == 0){
|
|
|
- goto err;
|
|
|
- }
|
|
|
- EC_GROUP_free(ngroup);
|
|
|
|
|
|
- group = EC_KEY_get0_group(ecdh);
|
|
|
|
|
|
- p += 3;
|
|
|
-
|
|
|
-
|
|
|
- if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
|
|
|
- ((bn_ctx = BN_CTX_new()) == NULL)) {
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- encoded_pt_len = *p;
|
|
|
- p += 1;
|
|
|
-
|
|
|
- if(EC_POINT_oct2point(group, srvr_ecpoint, p, encoded_pt_len,
|
|
|
- bn_ctx) == 0){
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- p += encoded_pt_len;
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x1010000eL
|
|
|
+ if(curve_nid == NID_X25519){
|
|
|
+
|
|
|
+ EVP_PKEY *key = EVP_PKEY_new();
|
|
|
+
|
|
|
+ if (key == NULL || !EVP_PKEY_set_type(key, curve_nid)){
|
|
|
+ EVP_PKEY_free(key);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ p += 3;
|
|
|
+ encoded_pt_len = *p;
|
|
|
+ p += 1;
|
|
|
+
|
|
|
+ EVP_PKEY_set1_tls_encodedpoint(key, p, encoded_pt_len);
|
|
|
+ f->srvr_key = key;
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+#endif
|
|
|
+ if((ecdh = EC_KEY_new()) == NULL) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ ngroup = EC_GROUP_new_by_curve_name(curve_nid);
|
|
|
+
|
|
|
+ if(ngroup == NULL){
|
|
|
+ printf("couldn't get curve by name (%d)\n", curve_nid);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(EC_KEY_set_group(ecdh, ngroup) == 0){
|
|
|
+ printf("couldn't set group\n");
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ EC_GROUP_free(ngroup);
|
|
|
+
|
|
|
+ group = EC_KEY_get0_group(ecdh);
|
|
|
+
|
|
|
+ p += 3;
|
|
|
+
|
|
|
+
|
|
|
+ if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
|
|
|
+ ((bn_ctx = BN_CTX_new()) == NULL)) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ encoded_pt_len = *p;
|
|
|
+ p += 1;
|
|
|
+
|
|
|
+ if(EC_POINT_oct2point(group, srvr_ecpoint, p, encoded_pt_len,
|
|
|
+ bn_ctx) == 0){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ EC_KEY_set_public_key(ecdh, srvr_ecpoint);
|
|
|
+ f->ecdh = ecdh;
|
|
|
|
|
|
- EC_KEY_set_public_key(ecdh, srvr_ecpoint);
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x1010000eL
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
- f->ecdh = ecdh;
|
|
|
ecdh = NULL;
|
|
|
BN_CTX_free(bn_ctx);
|
|
|
bn_ctx = NULL;
|
|
@@ -699,10 +714,54 @@ int compute_master_secret(flow *f){
|
|
|
|
|
|
|
|
|
} else if(f->keyex_alg == 2){
|
|
|
- const EC_GROUP *srvr_group = NULL;
|
|
|
- const EC_POINT *srvr_ecpoint = NULL;
|
|
|
- EC_KEY *tkey;
|
|
|
+ const EC_GROUP *srvr_group = NULL;
|
|
|
+ const EC_POINT *srvr_ecpoint = NULL;
|
|
|
+ EC_KEY *tkey;
|
|
|
+
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x1010000eL
|
|
|
+ if(f->srvr_key != NULL){
|
|
|
+
|
|
|
+ EVP_PKEY *ckey, *skey;
|
|
|
+ EVP_PKEY_CTX *pctx;
|
|
|
+ skey = f->srvr_key;
|
|
|
+
|
|
|
+
|
|
|
+ X25519_KEY *xkey = OPENSSL_zalloc(sizeof(*xkey));
|
|
|
+ xkey->privkey = OPENSSL_secure_malloc(X25519_KEYLEN);
|
|
|
+
|
|
|
+ if(xkey->privkey == NULL){
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ PRF(f, f->key, 16, (uint8_t *) SLITHEEN_KEYGEN_CONST, SLITHEEN_KEYGEN_CONST_SIZE,
|
|
|
+ NULL, 0, NULL, 0, NULL, 0, xkey->privkey, X25519_KEYLEN);
|
|
|
|
|
|
+#ifdef DEBUG_HS
|
|
|
+ printf("Generated the X25519 client private key [len: %d]: ", X25519_KEYLEN);
|
|
|
+ for(int i=0; i< X25519_KEYLEN; i++){
|
|
|
+ printf("%02x ", xkey->privkey[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+#endif
|
|
|
+
|
|
|
+ ckey = EVP_PKEY_new();
|
|
|
+ EVP_PKEY_assign(ckey, NID_X25519, xkey);
|
|
|
+
|
|
|
+ pctx = EVP_PKEY_CTX_new(ckey, NULL);
|
|
|
+
|
|
|
+ if (EVP_PKEY_derive_init(pctx) <= 0
|
|
|
+ || EVP_PKEY_derive_set_peer(pctx, skey) <= 0
|
|
|
+ || EVP_PKEY_derive(pctx, NULL, (uint64_t *) &pre_master_len) <= 0) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (EVP_PKEY_derive(pctx, pre_master_secret, (uint64_t *) &pre_master_len) <= 0)
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ EVP_PKEY_CTX_free(pctx);
|
|
|
+
|
|
|
+ } else {
|
|
|
+#endif
|
|
|
tkey = f->ecdh;
|
|
|
if(tkey == NULL){
|
|
|
return 1;
|
|
@@ -785,6 +844,9 @@ int compute_master_secret(flow *f){
|
|
|
if(pre_master_len <= 0) {
|
|
|
goto err;
|
|
|
}
|
|
|
+#if OPENSSL_VERSION_NUMBER >= 0x1010000eL
|
|
|
+ }
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
|