1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (c) 2014, Google Inc.
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Permission to use, copy, modify, and/or distribute this software for any
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * purpose with or without fee is hereby granted, provided that the above
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copyright notice and this permission notice appear in all copies.
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdio.h>
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h>
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <string>
19e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <vector>
20e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/base64.h>
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bio.h>
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h>
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ssl.h>
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
26e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "test/scoped_types.h"
27e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
28e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystruct ExpectedCipher {
29e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  unsigned long id;
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int in_group_flag;
31e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley};
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
33e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystruct CipherTest {
34e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // The rule string to apply.
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const char *rule;
36e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // The list of expected ciphers, in order, terminated with -1.
37e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  const ExpectedCipher *expected;
38e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley};
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
40e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// Selecting individual ciphers should work.
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule1[] =
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-CHACHA20-POLY1305:"
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-CHACHA20-POLY1305:"
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-AES128-GCM-SHA256:"
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-AES128-GCM-SHA256";
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
47e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected1[] = {
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
52e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
55e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// + reorders selected ciphers to the end, keeping their relative
56e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// order.
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule2[] =
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-CHACHA20-POLY1305:"
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-CHACHA20-POLY1305:"
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-AES128-GCM-SHA256:"
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-AES128-GCM-SHA256:"
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "+aRSA";
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
64e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected2[] = {
65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
69e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
72e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// ! banishes ciphers from future selections.
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule3[] =
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "!aRSA:"
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-CHACHA20-POLY1305:"
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-CHACHA20-POLY1305:"
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-AES128-GCM-SHA256:"
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-AES128-GCM-SHA256";
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
80e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected3[] = {
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
83e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
86e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// Multiple masks can be ANDed in a single rule.
87d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule4[] = "kRSA+AESGCM+AES128";
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
89e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected4[] = {
90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
91e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
94e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// - removes selected ciphers, but preserves their order for future
95e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// selections. Select AES_128_GCM, but order the key exchanges RSA,
96e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// DHE_RSA, ECDHE_RSA.
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule5[] =
98e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "AESGCM+AES128+aRSA";
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
101e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected5[] = {
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
105e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
108e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// Unknown selectors are no-ops.
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule6[] =
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-CHACHA20-POLY1305:"
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-CHACHA20-POLY1305:"
112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-ECDSA-AES128-GCM-SHA256:"
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-AES128-GCM-SHA256:"
114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4";
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
116e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected6[] = {
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
121e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
124e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// Square brackets specify equi-preference groups.
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule7[] =
126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "[ECDHE-RSA-CHACHA20-POLY1305]:"
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ECDHE-RSA-AES128-GCM-SHA256";
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
130e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected7[] = {
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 1 },
132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
135e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
138e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// @STRENGTH performs a stable strength-sort of the selected
139e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// ciphers and only the selected ciphers.
140d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kRule8[] =
141e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    // To simplify things, banish all but {ECDHE_RSA,RSA} x
142e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
144e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    // Order some ciphers backwards by strength.
145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
146e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    // Select ECDHE ones and sort them by strength. Ties should resolve
147e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    // based on the order above.
148e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "kECDHE:@STRENGTH:-ALL:"
149e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    // Now bring back everything uses RSA. ECDHE_RSA should be first,
150e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    // sorted by strength. Then RSA, backwards by strength.
151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "aRSA";
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
153e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected8[] = {
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 },
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 },
157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 },
158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { SSL3_CK_RSA_RC4_128_SHA, 0 },
159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { TLS1_CK_RSA_WITH_AES_256_SHA, 0 },
161e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
162e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley};
163e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
164e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// Exact ciphers may not be used in multi-part rules; they are treated
165e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// as unknown aliases.
166e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const char kRule9[] =
167e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "ECDHE-ECDSA-CHACHA20-POLY1305:"
168e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "ECDHE-RSA-CHACHA20-POLY1305:"
169e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
170e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305";
171e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
172e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const ExpectedCipher kExpected9[] = {
173e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
174e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
175e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { 0, 0 },
176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
178e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic CipherTest kCipherTests[] = {
179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule1, kExpected1 },
180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule2, kExpected2 },
181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule3, kExpected3 },
182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule4, kExpected4 },
183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule5, kExpected5 },
184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule6, kExpected6 },
185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule7, kExpected7 },
186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { kRule8, kExpected8 },
187e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { kRule9, kExpected9 },
188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  { NULL, NULL },
189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
191d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char *kBadRules[] = {
192e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Invalid brackets.
193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "RSA]",
195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "[[RSA]]",
196e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Operators inside brackets.
197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "[+RSA]",
198e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Unknown directive.
199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "@BOGUS",
200e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Empty cipher lists error at SSL_CTX_set_cipher_list.
201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "",
202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "BOGUS",
203e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // COMPLEMENTOFDEFAULT is empty.
204e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  "COMPLEMENTOFDEFAULT",
205e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Invalid command.
206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "?BAR",
207e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Special operators are not allowed if groups are used.
208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  NULL,
213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley};
214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
215e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
216e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  bool in_group = false;
217e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!in_group && list->in_group_flags[i]) {
220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      fprintf(stderr, "\t[\n");
221e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      in_group = true;
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "\t");
224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (in_group) {
225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      fprintf(stderr, "  ");
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (in_group && !list->in_group_flags[i]) {
229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      fprintf(stderr, "\t]\n");
230e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      in_group = false;
231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
235e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic bool TestCipherRule(CipherTest *t) {
236e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
237e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!ctx) {
238e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
239e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
241e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!SSL_CTX_set_cipher_list(ctx.get(), t->rule)) {
242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "Error testing cipher rule '%s'\n", t->rule);
243e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
246e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Compare the two lists.
247e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  size_t i;
248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  for (i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    const SSL_CIPHER *cipher =
250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (t->expected[i].id != SSL_CIPHER_get_id(cipher) ||
252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        t->expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
253e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
254e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      PrintCipherPreferenceList(ctx->cipher_list);
255e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return false;
256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
259e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (t->expected[i].id != 0) {
260e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
261e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    PrintCipherPreferenceList(ctx->cipher_list);
262e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
265e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return true;
266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
268e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic bool TestCipherRules() {
269e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  for (size_t i = 0; kCipherTests[i].rule != NULL; i++) {
270e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    if (!TestCipherRule(&kCipherTests[i])) {
271e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return false;
272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
275e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  for (size_t i = 0; kBadRules[i] != NULL; i++) {
276e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
277e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    if (!ctx) {
278e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return false;
279e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    }
280e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    if (SSL_CTX_set_cipher_list(ctx.get(), kBadRules[i])) {
281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", kBadRules[i]);
282e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return false;
283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ERR_clear_error();
285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
287e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return true;
288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
290e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
291e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// s_client -sess_out.
292d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kOpenSSLSession[] =
293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
296d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "i4gv7Y5oliyn";
324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
325e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// kCustomSession is a custom serialized SSL_SESSION generated by
326e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// filling in missing fields from |kOpenSSLSession|. This includes
327e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley// providing |peer_sha256|, so |peer| is not serialized.
328d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char kCustomSession[] =
329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
33853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
33953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// the final (optional) element of |kCustomSession| with tag number 30.
34053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langleystatic const char kBadSessionExtraField[] =
34153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
34253b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
34353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
34453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
34553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
34653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
34753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
34853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
34953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley
35053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
35153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley// the version of |kCustomSession| with 2.
35253b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langleystatic const char kBadSessionVersion[] =
35353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
35453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
35553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
35653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
35753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
35853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
35953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
36053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
36153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley
362e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t len;
364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!EVP_DecodedLength(&len, strlen(in))) {
365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "EVP_DecodedLength failed\n");
366e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
369e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  out->resize(len);
370e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!EVP_DecodeBase64(bssl::vector_data(out), &len, len, (const uint8_t *)in,
371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        strlen(in))) {
372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "EVP_DecodeBase64 failed\n");
373e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
375e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  out->resize(len);
376e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return true;
377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
379e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic bool TestSSL_SESSIONEncoding(const char *input_b64) {
380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const uint8_t *cptr;
381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t *ptr;
382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
383e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Decode the input.
384e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  std::vector<uint8_t> input;
385e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!DecodeBase64(&input, input_b64)) {
386e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
389e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Verify the SSL_SESSION decodes.
390e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  cptr = bssl::vector_data(&input);
391e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ScopedSSL_SESSION session(d2i_SSL_SESSION(NULL, &cptr, input.size()));
392e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!session || cptr != bssl::vector_data(&input) + input.size()) {
393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "d2i_SSL_SESSION failed\n");
394e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
397e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Verify the SSL_SESSION encoding round-trips.
398e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  size_t encoded_len;
399e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ScopedOpenSSLBytes encoded;
400e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  uint8_t *encoded_raw;
401e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
403e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
405e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  encoded.reset(encoded_raw);
406e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (encoded_len != input.size() ||
407e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
409e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
412e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // Verify the SSL_SESSION encoding round-trips via the legacy API.
413e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  int len = i2d_SSL_SESSION(session.get(), NULL);
414e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (len < 0 || (size_t)len != input.size()) {
415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
416e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
419e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
420e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!encoded) {
421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "malloc failed\n");
422e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
424e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
425e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ptr = encoded.get();
426e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  len = i2d_SSL_SESSION(session.get(), &ptr);
427e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (len < 0 || (size_t)len != input.size()) {
428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
429e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
431e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (ptr != encoded.get() + input.size()) {
432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
433e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
435e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
437e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
440e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return true;
441e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
44353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langleystatic bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
44453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  std::vector<uint8_t> input;
44553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  if (!DecodeBase64(&input, input_b64)) {
44653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    return false;
44753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  }
44853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley
44953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  // Verify that the SSL_SESSION fails to decode.
45053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  const uint8_t *ptr = bssl::vector_data(&input);
45153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  ScopedSSL_SESSION session(d2i_SSL_SESSION(NULL, &ptr, input.size()));
45253b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  if (session) {
45353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    fprintf(stderr, "d2i_SSL_SESSION unexpectedly succeeded\n");
45453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    return false;
45553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  }
45653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  ERR_clear_error();
45753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  return true;
45853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley}
45953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley
460e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic bool TestDefaultVersion(uint16_t version,
461e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                               const SSL_METHOD *(*method)(void)) {
462e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ScopedSSL_CTX ctx(SSL_CTX_new(method()));
463e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!ctx) {
464e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
466e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ctx->min_version == version && ctx->max_version == version;
467e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
469e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic bool CipherGetRFCName(std::string *out, uint16_t value) {
470e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
471e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (cipher == NULL) {
472e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return false;
473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
474e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
47553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  if (!rfc_name) {
47653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley    return false;
47753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley  }
478e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  out->assign(rfc_name.get());
479e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return true;
480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
481d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
482e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleytypedef struct {
483e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  int id;
484e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  const char *rfc_name;
485e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} CIPHER_RFC_NAME_TEST;
486e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
487e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
488e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
489e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
490e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
491e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
492e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
493e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
494e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
495e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
496e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
497e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
498e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
499e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
500e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
501e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
502e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
503e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
504e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
505dfb3ba68fd0011cba7d8e4c1a46295099fef85bfAdam Langley  { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
506dfb3ba68fd0011cba7d8e4c1a46295099fef85bfAdam Langley    "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
507e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  // These names are non-standard:
508e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
509e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
510e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305,
511e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
512e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley};
513d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
514e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic bool TestCipherGetRFCName(void) {
515e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  for (size_t i = 0;
516e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley       i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
517e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
518e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    std::string rfc_name;
519e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
520e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
521e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return false;
522e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    }
523e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    if (rfc_name != test->rfc_name) {
524e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
525e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley              rfc_name.c_str(), test->rfc_name);
526e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return false;
527e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    }
528d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
529e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return true;
530d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
531d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
532d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint main(void) {
533d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_library_init();
534d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
535e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!TestCipherRules() ||
536e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
537e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestSSL_SESSIONEncoding(kCustomSession) ||
53853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley      !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
53953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley      !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
540e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(0, &TLS_method) ||
541e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(SSL3_VERSION, &SSLv3_method) ||
542e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(TLS1_VERSION, &TLSv1_method) ||
543e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(TLS1_1_VERSION, &TLSv1_1_method) ||
544e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(TLS1_2_VERSION, &TLSv1_2_method) ||
545e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(0, &DTLS_method) ||
546e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(DTLS1_VERSION, &DTLSv1_method) ||
547e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) ||
548e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      !TestCipherGetRFCName()) {
549e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    ERR_print_errors_fp(stderr);
550d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
551d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
552d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
553d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  printf("PASS\n");
554d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
555d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
556