Skip to content

Commit 1cdac45

Browse files
committed
day 3
1 parent dc96c44 commit 1cdac45

File tree

10 files changed

+933
-181
lines changed

10 files changed

+933
-181
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "deps/picotest"]
2+
path = deps/picotest
3+
url = https://github.com/h2o/picotest.git

deps/picotest

Submodule picotest added at d088dc1

include/picotls.h

+77-6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#ifndef picotls_h
2323
#define picotls_h
2424

25+
#include <inttypes.h>
26+
27+
#define PTLS_MAX_DIGEST_SIZE 64
28+
2529
/* cipher-suites */
2630
#define PTLS_CIPHER_SUITE_AES_128_GCM_SHA256 0x1301
2731
#define PTLS_CIPHER_SUITE_AES_256_GCM_SHA384 0x1302
@@ -47,22 +51,71 @@
4751

4852
typedef struct st_ptls_t ptls_t;
4953

54+
typedef struct st_ptls_iovec_t {
55+
uint8_t *base;
56+
size_t len;
57+
} ptls_iovec_t;
58+
59+
typedef struct st_ptls_crypto_t ptls_crypto_t;
60+
5061
typedef struct st_ptls_context_t {
62+
ptls_crypto_t *crypto;
5163
struct {
52-
int (*server_name)(ptls_t *tls, X509 **cert, STACK_OF(X509) * *extra_certs);
64+
int (*server_name)(ptls_t *tls, ptls_iovec_t **certs, size_t *num_certs, void **signer);
5365
} callbacks;
5466
} ptls_context_t;
5567

68+
typedef struct st_ptls_key_exchange_algorithm_t {
69+
uint16_t id;
70+
int (*key_exchange)(ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey);
71+
} ptls_key_exchange_algorithm_t;
72+
5673
typedef struct st_ptls_aead_context_t {
74+
void (*destroy)(struct st_ptls_aead_context_t *ctx);
75+
size_t (*transform)(struct st_ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen);
76+
uint64_t nonce;
77+
} ptls_aead_context_t;
78+
79+
typedef struct st_ptls_aead_algorithm_t {
80+
size_t key_size;
81+
size_t block_size;
82+
ptls_aead_context_t *(*create)(const uint8_t *key);
83+
} ptls_aead_algorithm_t;
84+
85+
typedef enum en_ptls_hash_final_mode_t {
86+
PTLS_HASH_FINAL_MODE_FREE = 0,
87+
PTLS_HASH_FINAL_MODE_RESET = 1,
88+
PTLS_HASH_FINAL_MODE_SNAPSHOT = 2
89+
} ptls_hash_final_mode_t;
90+
91+
typedef struct st_ptls_hash_context_t {
92+
void (*update)(struct st_ptls_hash_context_t *ctx, const void *src, size_t len);
93+
void (* final)(struct st_ptls_hash_context_t *ctx, void *md, ptls_hash_final_mode_t mode);
94+
} ptls_hash_context_t;
95+
96+
typedef struct st_ptls_hash_algorithm_t {
97+
size_t block_size;
98+
size_t digest_size;
99+
ptls_hash_context_t *(*create)(void);
100+
} ptls_hash_algorithm_t;
101+
102+
typedef struct st_ptls_cipher_suite_t {
103+
uint16_t id;
104+
ptls_aead_algorithm_t *aead;
105+
ptls_hash_algorithm_t *hash;
106+
} ptls_cipher_suite_t;
107+
108+
typedef struct st_ptls_crypto_t {
109+
void (*random_bytes)(void *buf, size_t len);
57110
/**
58-
*
111+
* list of supported key-exchange algorithms terminated by .id == UINT16_MAX
59112
*/
60-
uint64_t nonce;
113+
ptls_key_exchange_algorithm_t *key_exchanges;
61114
/**
62-
* callback used to encrypt a record
115+
* list of supported cipher-suites terminated by .id == UINT16_MAX
63116
*/
64-
size_t (*transform)(struct st_ptls_aead_context_t *ctx, uint8_t *output, const uint8_t *input, size_t inlen);
65-
} ptls_aead_context_t;
117+
ptls_cipher_suite_t *cipher_suites;
118+
} ptls_crypto_t;
66119

67120
/**
68121
*
@@ -88,5 +141,23 @@ int ptls_decrypt(ptls_t *tls, const void *encrypted, size_t *enclen, void *dst,
88141
*
89142
*/
90143
int ptls_enrypt(ptls_t *tls, const void *src, size_t *srclen, void *encrypted, size_t *enclen);
144+
/**
145+
*
146+
*/
147+
ptls_hash_context_t *ptls_hmac_create(ptls_hash_algorithm_t *algo, const void *key, size_t key_size);
148+
/**
149+
*
150+
*/
151+
void ptls_hkdf_extract(ptls_hash_algorithm_t *hash, void *output, ptls_iovec_t salt, ptls_iovec_t ikm);
152+
/**
153+
*
154+
*/
155+
void ptls_hkdf_expand(ptls_hash_algorithm_t *hash, void *output, size_t outlen, ptls_iovec_t prk, ptls_iovec_t info);
156+
/**
157+
* clears memory
158+
*/
159+
extern void (*volatile ptls_clear_memory)(void *p, size_t len);
160+
161+
extern ptls_crypto_t ptls_crypto_openssl;
91162

92163
#endif

lib/crypto-openssl.c

+230
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/*
2+
* Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to
6+
* deal in the Software without restriction, including without limitation the
7+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8+
* sell copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20+
* IN THE SOFTWARE.
21+
*/
22+
#include <assert.h>
23+
#include <stdlib.h>
24+
#include <openssl/bn.h>
25+
#include <openssl/ec.h>
26+
#include <openssl/ecdh.h>
27+
#include <openssl/err.h>
28+
#include <openssl/crypto.h>
29+
#include <openssl/objects.h>
30+
#include <openssl/rand.h>
31+
#include <openssl/x509.h>
32+
#include "picotls.h"
33+
34+
static void random_bytes(void *buf, size_t len)
35+
{
36+
RAND_bytes(buf, (int)len);
37+
}
38+
39+
static EC_KEY *ecdh_gerenate_key(EC_GROUP *group)
40+
{
41+
EC_KEY *key;
42+
43+
if ((key = EC_KEY_new()) == NULL)
44+
return NULL;
45+
if (!EC_KEY_set_group(key, group) || !EC_KEY_generate_key(key)) {
46+
EC_KEY_free(key);
47+
return NULL;
48+
}
49+
50+
return key;
51+
}
52+
53+
static EC_POINT *x9_62_decode_point(EC_GROUP *group, ptls_iovec_t vec, BN_CTX *bn_ctx)
54+
{
55+
EC_POINT *point = NULL;
56+
57+
if ((point = EC_POINT_new(group)) == NULL)
58+
return NULL;
59+
if (!EC_POINT_oct2point(group, point, vec.base, vec.len, bn_ctx)) {
60+
EC_POINT_free(point);
61+
return NULL;
62+
}
63+
64+
return point;
65+
}
66+
67+
static ptls_iovec_t x9_62_encode_point(EC_GROUP *group, const EC_POINT *point, BN_CTX *bn_ctx)
68+
{
69+
ptls_iovec_t vec;
70+
71+
if ((vec.len = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx)) == 0)
72+
return (ptls_iovec_t){NULL};
73+
if ((vec.base = malloc(vec.len)) == NULL)
74+
return (ptls_iovec_t){NULL};
75+
if (EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, vec.base, vec.len, bn_ctx) != vec.len) {
76+
free(vec.base);
77+
return (ptls_iovec_t){NULL};
78+
}
79+
80+
return vec;
81+
}
82+
83+
static int x9_62_key_exchange(EC_GROUP *group, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey, BN_CTX *bn_ctx)
84+
{
85+
EC_POINT *peer_point = NULL;
86+
EC_KEY *privkey = NULL;
87+
int ret;
88+
89+
*pubkey = (ptls_iovec_t){NULL};
90+
*secret = (ptls_iovec_t){NULL};
91+
92+
/* decode peer key */
93+
if ((peer_point = x9_62_decode_point(group, peerkey, bn_ctx)) == NULL) {
94+
ret = PTLS_ALERT_DECODE_ERROR;
95+
goto Exit;
96+
}
97+
98+
/* create private key */
99+
if ((privkey = ecdh_gerenate_key(group)) == NULL) {
100+
ret = PTLS_ERROR_NO_MEMORY;
101+
goto Exit;
102+
}
103+
104+
/* encode public key */
105+
if ((*pubkey = x9_62_encode_point(group, EC_KEY_get0_public_key(privkey), bn_ctx)).base == NULL) {
106+
ret = PTLS_ERROR_NO_MEMORY;
107+
goto Exit;
108+
}
109+
110+
/* calc secret */
111+
secret->len = (EC_GROUP_get_degree(group) + 7) / 8;
112+
if ((secret->base = malloc(secret->len)) == NULL) {
113+
ret = PTLS_ERROR_NO_MEMORY;
114+
goto Exit;
115+
}
116+
117+
/* ecdh! */
118+
if (ECDH_compute_key(secret->base, secret->len, peer_point, privkey, NULL) <= 0) {
119+
ret = PTLS_ALERT_HANDSHAKE_FAILURE; /* ??? */
120+
goto Exit;
121+
}
122+
123+
ret = 0;
124+
125+
Exit:
126+
if (peer_point != NULL)
127+
EC_POINT_free(peer_point);
128+
if (privkey != NULL)
129+
EC_KEY_free(privkey);
130+
if (ret != 0) {
131+
free(pubkey->base);
132+
*pubkey = (ptls_iovec_t){NULL};
133+
free(secret->base);
134+
*secret = (ptls_iovec_t){NULL};
135+
}
136+
return ret;
137+
}
138+
139+
static int secp_key_exchange(int nid, ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey)
140+
{
141+
EC_GROUP *group = NULL;
142+
BN_CTX *bn_ctx = NULL;
143+
int ret;
144+
145+
if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
146+
ret = PTLS_ERROR_LIBRARY;
147+
goto Exit;
148+
}
149+
if ((bn_ctx = BN_CTX_new()) != NULL) {
150+
ret = PTLS_ERROR_NO_MEMORY;
151+
goto Exit;
152+
}
153+
154+
ret = x9_62_key_exchange(group, pubkey, secret, peerkey, bn_ctx);
155+
156+
Exit:
157+
if (bn_ctx != NULL)
158+
BN_CTX_free(bn_ctx);
159+
if (group != NULL)
160+
EC_GROUP_free(group);
161+
return ret;
162+
}
163+
164+
static int secp256r1_key_exchange(ptls_iovec_t *pubkey, ptls_iovec_t *secret, ptls_iovec_t peerkey)
165+
{
166+
return secp_key_exchange(NID_X9_62_prime256v1, pubkey, secret, peerkey);
167+
}
168+
169+
static ptls_aead_context_t *aead_aes128gcm_create(const uint8_t *key)
170+
{
171+
return NULL;
172+
}
173+
174+
struct sha256_context_t {
175+
ptls_hash_context_t super;
176+
SHA256_CTX ctx;
177+
};
178+
179+
static void sha256_update(ptls_hash_context_t *_ctx, const void *src, size_t len)
180+
{
181+
struct sha256_context_t *ctx = (struct sha256_context_t *)_ctx;
182+
183+
SHA256_Update(&ctx->ctx, src, len);
184+
}
185+
186+
static void sha256_final(ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode)
187+
{
188+
struct sha256_context_t *ctx = (struct sha256_context_t *)_ctx;
189+
190+
if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) {
191+
SHA256_CTX copy = ctx->ctx;
192+
SHA256_Final(md, &copy);
193+
ptls_clear_memory(&copy, sizeof(copy));
194+
return;
195+
}
196+
197+
if (md != NULL)
198+
SHA256_Final(md, &ctx->ctx);
199+
200+
switch (mode) {
201+
case PTLS_HASH_FINAL_MODE_FREE:
202+
ptls_clear_memory(&ctx->ctx, sizeof(ctx->ctx));
203+
free(ctx);
204+
break;
205+
case PTLS_HASH_FINAL_MODE_RESET:
206+
SHA256_Init(&ctx->ctx);
207+
break;
208+
default:
209+
assert(!"FIXME");
210+
break;
211+
}
212+
}
213+
214+
static ptls_hash_context_t *sha256_create(void)
215+
{
216+
struct sha256_context_t *ctx;
217+
218+
if ((ctx = malloc(sizeof(*ctx))) == NULL)
219+
return NULL;
220+
ctx->super = (ptls_hash_context_t){sha256_update, sha256_final};
221+
SHA256_Init(&ctx->ctx);
222+
return &ctx->super;
223+
}
224+
225+
static ptls_key_exchange_algorithm_t key_exchanges[] = {{PTLS_GROUP_SECP256R1, secp256r1_key_exchange}, {UINT16_MAX}};
226+
static ptls_aead_algorithm_t aes128gcm = {16, 16, aead_aes128gcm_create};
227+
static ptls_hash_algorithm_t sha256 = {64, 32, sha256_create};
228+
static ptls_cipher_suite_t cipher_suites[] = {{PTLS_CIPHER_SUITE_AES_128_GCM_SHA256, &aes128gcm, &sha256}, {UINT16_MAX}};
229+
230+
ptls_crypto_t ptls_crypto_openssl = {random_bytes, key_exchanges, cipher_suites};

0 commit comments

Comments
 (0)