From 751e889b1d791d2b91c1437248454fa1d4e101a5 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 19 Oct 2014 00:59:36 -0400 Subject: [PATCH] Add SSL_SESSION serialization and deserialization tests. Change-Id: Ia59e4accb644c8807b7c4ab6267efa624be95c18 Reviewed-on: https://boringssl-review.googlesource.com/1992 Reviewed-by: Adam Langley --- ssl/ssl_test.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/ssl/ssl_test.c b/ssl/ssl_test.c index 68889a0a..a2022732 100644 --- a/ssl/ssl_test.c +++ b/ssl/ssl_test.c @@ -13,7 +13,10 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include +#include +#include +#include #include #include @@ -265,10 +268,172 @@ static int test_cipher_rules(void) { return 1; } +/* kOpenSSLSession is a serialized SSL_SESSION generated from openssl + * s_client -sess_out. */ +static const char kOpenSSLSession[] = + "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" + "i4gv7Y5oliyn"; + +/* kCustomSession is a custom serialized SSL_SESSION generated by + * filling in missing fields from |kOpenSSLSession|. This includes + * providing |peer_sha256|, so |peer| is not serialized. */ +static const char kCustomSession[] = + "MIIBggIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ" + "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH" + "IWoJgAEBoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29t" + "pwcEBWhlbGxvqAcEBXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXq" + "KwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362z" + "ZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3" + "+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5o" + "liynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQB" + "BLADBAEF"; + +/* kCustomSession2 is kCustomSession with the old SSLv2-only key_arg + * field removed. Encoding the decoded version of kCustomSession + * should not preserve key_arg. */ +static const char kCustomSession2[] = + "MIIBfwIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ" + "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH" + "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tpwcE" + "BWhlbGxvqAcEBXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOB" + "fF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY2" + "7GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inb" + "MaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliyn" + "rSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLAD" + "BAEF"; + +static int decode_base64(uint8_t **out, size_t *out_len, const char *in) { + size_t len; + + if (!EVP_DecodedLength(&len, strlen(in))) { + fprintf(stderr, "EVP_DecodedLength failed\n"); + return 0; + } + + *out = OPENSSL_malloc(len); + if (*out == NULL) { + fprintf(stderr, "malloc failed\n"); + return 0; + } + + if (!EVP_DecodeBase64(*out, out_len, len, (const uint8_t *)in, + strlen(in))) { + fprintf(stderr, "EVP_DecodeBase64 failed\n"); + OPENSSL_free(*out); + *out = NULL; + return 0; + } + return 1; +} + +static int test_ssl_session_asn1(const char *input_b64, + const char *expected_b64) { + int ret = 0, len; + size_t input_len, expected_len; + uint8_t *input = NULL, *expected = NULL, *encoded = NULL; + const uint8_t *cptr; + uint8_t *ptr; + SSL_SESSION *session = NULL; + + /* Decode the input. */ + if (!decode_base64(&input, &input_len, input_b64) || + !decode_base64(&expected, &expected_len, expected_b64)) { + goto done; + } + + /* Verify the SSL_SESSION decodes. */ + cptr = input; + session = d2i_SSL_SESSION(NULL, &cptr, input_len); + if (session == NULL || cptr != input + input_len) { + fprintf(stderr, "d2i_SSL_SESSION failed\n"); + goto done; + } + + /* Verify the SSL_SESSION encoding round-trips. */ + len = i2d_SSL_SESSION(session, NULL); + if (len < 0 || (size_t)len != expected_len) { + fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n"); + goto done; + } + + encoded = OPENSSL_malloc(expected_len); + if (encoded == NULL) { + fprintf(stderr, "malloc failed\n"); + goto done; + } + ptr = encoded; + len = i2d_SSL_SESSION(session, &ptr); + if (len < 0 || (size_t)len != expected_len) { + fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n"); + goto done; + } + if (ptr != encoded + expected_len) { + fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n"); + goto done; + } + if (memcmp(expected, encoded, expected_len) != 0) { + fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n"); + goto done; + } + + ret = 1; + + done: + if (!ret) { + BIO_print_errors_fp(stderr); + } + + if (session) { + SSL_SESSION_free(session); + } + if (input) { + OPENSSL_free(input); + } + if (expected) { + OPENSSL_free(expected); + } + if (encoded) { + OPENSSL_free(encoded); + } + return ret; +} + int main(void) { SSL_library_init(); - if (!test_cipher_rules()) { + if (!test_cipher_rules() || + !test_ssl_session_asn1(kOpenSSLSession, kOpenSSLSession) || + !test_ssl_session_asn1(kCustomSession, kCustomSession2) || + !test_ssl_session_asn1(kCustomSession2, kCustomSession2)) { return 1; }