1*4724848cSchristos /*
2*4724848cSchristos * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
3*4724848cSchristos *
4*4724848cSchristos * Licensed under the OpenSSL license (the "License"). You may not use
5*4724848cSchristos * this file except in compliance with the License. You can obtain a copy
6*4724848cSchristos * in the file LICENSE in the source distribution or at
7*4724848cSchristos * https://www.openssl.org/source/license.html
8*4724848cSchristos */
9*4724848cSchristos
10*4724848cSchristos #include <string.h>
11*4724848cSchristos #include <openssl/bio.h>
12*4724848cSchristos #include <openssl/pem.h>
13*4724848cSchristos
14*4724848cSchristos #include "testutil.h"
15*4724848cSchristos #include "internal/nelem.h"
16*4724848cSchristos
17*4724848cSchristos typedef struct {
18*4724848cSchristos const char *raw;
19*4724848cSchristos const char *encoded;
20*4724848cSchristos } TESTDATA;
21*4724848cSchristos
22*4724848cSchristos static TESTDATA b64_pem_data[] = {
23*4724848cSchristos { "hello world",
24*4724848cSchristos "aGVsbG8gd29ybGQ=" },
25*4724848cSchristos { "a very ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong input",
26*4724848cSchristos "YSB2ZXJ5IG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyBpbnB1dA==" }
27*4724848cSchristos };
28*4724848cSchristos
29*4724848cSchristos static const char *pemtype = "PEMTESTDATA";
30*4724848cSchristos
test_b64(int idx)31*4724848cSchristos static int test_b64(int idx)
32*4724848cSchristos {
33*4724848cSchristos BIO *b = BIO_new(BIO_s_mem());
34*4724848cSchristos char *name = NULL, *header = NULL;
35*4724848cSchristos unsigned char *data = NULL;
36*4724848cSchristos long len;
37*4724848cSchristos int ret = 0;
38*4724848cSchristos const char *raw = b64_pem_data[idx].raw;
39*4724848cSchristos const char *encoded = b64_pem_data[idx].encoded;
40*4724848cSchristos
41*4724848cSchristos if (!TEST_ptr(b)
42*4724848cSchristos || !TEST_true(BIO_printf(b, "-----BEGIN %s-----\n", pemtype))
43*4724848cSchristos || !TEST_true(BIO_printf(b, "%s\n", encoded))
44*4724848cSchristos || !TEST_true(BIO_printf(b, "-----END %s-----\n", pemtype))
45*4724848cSchristos || !TEST_true(PEM_read_bio_ex(b, &name, &header, &data, &len,
46*4724848cSchristos PEM_FLAG_ONLY_B64)))
47*4724848cSchristos goto err;
48*4724848cSchristos if (!TEST_int_eq(memcmp(pemtype, name, strlen(pemtype)), 0)
49*4724848cSchristos || !TEST_int_eq(len, strlen(raw))
50*4724848cSchristos || !TEST_int_eq(memcmp(data, raw, strlen(raw)), 0))
51*4724848cSchristos goto err;
52*4724848cSchristos ret = 1;
53*4724848cSchristos err:
54*4724848cSchristos BIO_free(b);
55*4724848cSchristos OPENSSL_free(name);
56*4724848cSchristos OPENSSL_free(header);
57*4724848cSchristos OPENSSL_free(data);
58*4724848cSchristos return ret;
59*4724848cSchristos }
60*4724848cSchristos
test_invalid(void)61*4724848cSchristos static int test_invalid(void)
62*4724848cSchristos {
63*4724848cSchristos BIO *b = BIO_new(BIO_s_mem());
64*4724848cSchristos char *name = NULL, *header = NULL;
65*4724848cSchristos unsigned char *data = NULL;
66*4724848cSchristos long len;
67*4724848cSchristos const char *encoded = b64_pem_data[0].encoded;
68*4724848cSchristos
69*4724848cSchristos if (!TEST_ptr(b)
70*4724848cSchristos || !TEST_true(BIO_printf(b, "-----BEGIN %s-----\n", pemtype))
71*4724848cSchristos || !TEST_true(BIO_printf(b, "%c%s\n", '\t', encoded))
72*4724848cSchristos || !TEST_true(BIO_printf(b, "-----END %s-----\n", pemtype))
73*4724848cSchristos /* Expected to fail due to non-base64 character */
74*4724848cSchristos || TEST_true(PEM_read_bio_ex(b, &name, &header, &data, &len,
75*4724848cSchristos PEM_FLAG_ONLY_B64))) {
76*4724848cSchristos BIO_free(b);
77*4724848cSchristos return 0;
78*4724848cSchristos }
79*4724848cSchristos BIO_free(b);
80*4724848cSchristos OPENSSL_free(name);
81*4724848cSchristos OPENSSL_free(header);
82*4724848cSchristos OPENSSL_free(data);
83*4724848cSchristos return 1;
84*4724848cSchristos }
85*4724848cSchristos
test_empty_payload(void)86*4724848cSchristos static int test_empty_payload(void)
87*4724848cSchristos {
88*4724848cSchristos BIO *b;
89*4724848cSchristos static char *emptypay =
90*4724848cSchristos "-----BEGIN CERTIFICATE-----\n"
91*4724848cSchristos "-\n" /* Base64 EOF character */
92*4724848cSchristos "-----END CERTIFICATE-----";
93*4724848cSchristos char *name = NULL, *header = NULL;
94*4724848cSchristos unsigned char *data = NULL;
95*4724848cSchristos long len;
96*4724848cSchristos int ret = 0;
97*4724848cSchristos
98*4724848cSchristos b = BIO_new_mem_buf(emptypay, strlen(emptypay));
99*4724848cSchristos if (!TEST_ptr(b))
100*4724848cSchristos return 0;
101*4724848cSchristos
102*4724848cSchristos /* Expected to fail because the payload is empty */
103*4724848cSchristos if (!TEST_false(PEM_read_bio_ex(b, &name, &header, &data, &len, 0)))
104*4724848cSchristos goto err;
105*4724848cSchristos
106*4724848cSchristos ret = 1;
107*4724848cSchristos err:
108*4724848cSchristos OPENSSL_free(name);
109*4724848cSchristos OPENSSL_free(header);
110*4724848cSchristos OPENSSL_free(data);
111*4724848cSchristos BIO_free(b);
112*4724848cSchristos return ret;
113*4724848cSchristos }
114*4724848cSchristos
setup_tests(void)115*4724848cSchristos int setup_tests(void)
116*4724848cSchristos {
117*4724848cSchristos ADD_ALL_TESTS(test_b64, OSSL_NELEM(b64_pem_data));
118*4724848cSchristos ADD_TEST(test_invalid);
119*4724848cSchristos ADD_TEST(test_empty_payload);
120*4724848cSchristos return 1;
121*4724848cSchristos }
122