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 #ifndef _XOPEN_SOURCE
23 #define _XOPEN_SOURCE 700 /* required for glibc to use getaddrinfo, etc. */
24 #endif
25 #include <assert.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include "../deps/picotest/picotest.h"
29 #include "../lib/cifra.c"
30 #include "../lib/uecc.c"
31 #include "test.h"
32 
test_secp256r1_key_exchange(void)33 static void test_secp256r1_key_exchange(void)
34 {
35     test_key_exchange(&ptls_minicrypto_secp256r1, &ptls_minicrypto_secp256r1);
36 }
37 
test_x25519_key_exchange(void)38 static void test_x25519_key_exchange(void)
39 {
40     test_key_exchange(&ptls_minicrypto_x25519, &ptls_minicrypto_x25519);
41 }
42 
test_secp256r1_sign(void)43 static void test_secp256r1_sign(void)
44 {
45     const char *msg = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef";
46     ptls_minicrypto_secp256r1sha256_sign_certificate_t signer = {{secp256r1sha256_sign}};
47     uint8_t pub[SECP256R1_PUBLIC_KEY_SIZE];
48     uint16_t selected;
49     ptls_buffer_t sigbuf;
50     uint32_t sigbuf_small[128];
51 
52     uECC_make_key(pub, signer.key, uECC_secp256r1());
53     ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small));
54 
55     ok(secp256r1sha256_sign(&signer.super, NULL, &selected, &sigbuf, ptls_iovec_init(msg, 32),
56                             (uint16_t[]){PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256}, 1) == 0);
57     ok(selected == PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256);
58 
59     /* FIXME verify sign */
60 
61     ptls_buffer_dispose(&sigbuf);
62 }
63 
test_hrr(void)64 static void test_hrr(void)
65 {
66     ptls_key_exchange_algorithm_t *client_keyex[] = {&ptls_minicrypto_x25519, &ptls_minicrypto_secp256r1, NULL};
67     ptls_context_t client_ctx = {ptls_minicrypto_random_bytes, &ptls_get_time, client_keyex, ptls_minicrypto_cipher_suites};
68     ptls_t *client, *server;
69     ptls_buffer_t cbuf, sbuf, decbuf;
70     uint8_t cbuf_small[16384], sbuf_small[16384], decbuf_small[16384];
71     size_t consumed;
72     int ret;
73 
74     assert(ctx_peer->key_exchanges[0] != NULL && ctx_peer->key_exchanges[0]->id == PTLS_GROUP_SECP256R1);
75     assert(ctx_peer->key_exchanges[1] == NULL);
76 
77     client = ptls_new(&client_ctx, 0);
78     server = ptls_new(ctx_peer, 1);
79     ptls_buffer_init(&cbuf, cbuf_small, sizeof(cbuf_small));
80     ptls_buffer_init(&sbuf, sbuf_small, sizeof(sbuf_small));
81     ptls_buffer_init(&decbuf, decbuf_small, sizeof(decbuf_small));
82 
83     ret = ptls_handshake(client, &cbuf, NULL, NULL, NULL);
84     ok(ret == PTLS_ERROR_IN_PROGRESS);
85 
86     consumed = cbuf.off;
87     ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, NULL);
88     ok(ret == PTLS_ERROR_IN_PROGRESS);
89     ok(consumed == cbuf.off);
90     cbuf.off = 0;
91 
92     ok(sbuf.off > 5 + 4);
93     ok(sbuf.base[5] == 2 /* PTLS_HANDSHAKE_TYPE_SERVER_HELLO (RETRY_REQUEST) */);
94 
95     consumed = sbuf.off;
96     ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL);
97     ok(ret == PTLS_ERROR_IN_PROGRESS);
98     ok(consumed == sbuf.off);
99     sbuf.off = 0;
100 
101     ok(cbuf.off >= 5 + 4);
102     ok(cbuf.base[5] == 1 /* PTLS_HANDSHAKE_TYPE_CLIENT_HELLO */);
103 
104     consumed = cbuf.off;
105     ret = ptls_handshake(server, &sbuf, cbuf.base, &consumed, NULL);
106     ok(ret == 0);
107     ok(consumed == cbuf.off);
108     cbuf.off = 0;
109 
110     ok(sbuf.off >= 5 + 4);
111     ok(sbuf.base[5] == 2 /* PTLS_HANDSHAKE_TYPE_SERVER_HELLO */);
112 
113     consumed = sbuf.off;
114     ret = ptls_handshake(client, &cbuf, sbuf.base, &consumed, NULL);
115     ok(ret == 0);
116     ok(consumed == sbuf.off);
117     sbuf.off = 0;
118 
119     ret = ptls_send(client, &cbuf, "hello world", 11);
120     ok(ret == 0);
121 
122     consumed = cbuf.off;
123     ret = ptls_receive(server, &decbuf, cbuf.base, &consumed);
124     ok(ret == 0);
125     ok(consumed == cbuf.off);
126     cbuf.off = 0;
127 
128     ok(decbuf.off == 11);
129     ok(memcmp(decbuf.base, "hello world", 11) == 0);
130 
131     ptls_buffer_dispose(&decbuf);
132     ptls_buffer_dispose(&sbuf);
133     ptls_buffer_dispose(&cbuf);
134     ptls_free(client);
135     ptls_free(server);
136 }
137 
138 DEFINE_FFX_AES128_ALGORITHMS(minicrypto);
139 DEFINE_FFX_CHACHA20_ALGORITHMS(minicrypto);
140 
main(int argc,char ** argv)141 int main(int argc, char **argv)
142 {
143     subtest("secp256r1", test_secp256r1_key_exchange);
144     subtest("x25519", test_x25519_key_exchange);
145     subtest("secp256r1-sign", test_secp256r1_sign);
146 
147     ptls_iovec_t cert = ptls_iovec_init(SECP256R1_CERTIFICATE, sizeof(SECP256R1_CERTIFICATE) - 1);
148 
149     ptls_minicrypto_secp256r1sha256_sign_certificate_t sign_certificate;
150     ptls_minicrypto_init_secp256r1sha256_sign_certificate(&sign_certificate,
151                                                           ptls_iovec_init(SECP256R1_PRIVATE_KEY, SECP256R1_PRIVATE_KEY_SIZE));
152 
153     ptls_context_t ctxbuf = {ptls_minicrypto_random_bytes,
154                              &ptls_get_time,
155                              ptls_minicrypto_key_exchanges,
156                              ptls_minicrypto_cipher_suites,
157                              {&cert, 1},
158                              NULL,
159                              NULL,
160                              NULL,
161                              &sign_certificate.super};
162     ctx = ctx_peer = &ctxbuf;
163     ADD_FFX_AES128_ALGORITHMS(minicrypto);
164     ADD_FFX_CHACHA20_ALGORITHMS(minicrypto);
165 
166     subtest("picotls", test_picotls);
167     subtest("hrr", test_hrr);
168 
169     return done_testing();
170 }
171