1 /* 2 * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <string.h> 11 #include <openssl/bio.h> 12 #include <openssl/pem.h> 13 14 #include "testutil.h" 15 #include "internal/nelem.h" 16 17 typedef struct { 18 const char *raw; 19 const char *encoded; 20 } TESTDATA; 21 22 static TESTDATA b64_pem_data[] = { 23 { "hello world", 24 "aGVsbG8gd29ybGQ=" }, 25 { "a very ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong input", 26 "YSB2ZXJ5IG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyBpbnB1dA==" } 27 }; 28 29 static const char *pemtype = "PEMTESTDATA"; 30 31 static char *pemfile; 32 33 static int test_b64(int idx) 34 { 35 BIO *b = BIO_new(BIO_s_mem()); 36 char *name = NULL, *header = NULL; 37 unsigned char *data = NULL; 38 long len; 39 int ret = 0; 40 const char *raw = b64_pem_data[idx].raw; 41 const char *encoded = b64_pem_data[idx].encoded; 42 43 if (!TEST_ptr(b) 44 || !TEST_true(BIO_printf(b, "-----BEGIN %s-----\n", pemtype)) 45 || !TEST_true(BIO_printf(b, "%s\n", encoded)) 46 || !TEST_true(BIO_printf(b, "-----END %s-----\n", pemtype)) 47 || !TEST_true(PEM_read_bio_ex(b, &name, &header, &data, &len, 48 PEM_FLAG_ONLY_B64))) 49 goto err; 50 if (!TEST_int_eq(memcmp(pemtype, name, strlen(pemtype)), 0) 51 || !TEST_int_eq(len, strlen(raw)) 52 || !TEST_int_eq(memcmp(data, raw, strlen(raw)), 0)) 53 goto err; 54 ret = 1; 55 err: 56 BIO_free(b); 57 OPENSSL_free(name); 58 OPENSSL_free(header); 59 OPENSSL_free(data); 60 return ret; 61 } 62 63 static int test_invalid(void) 64 { 65 BIO *b = BIO_new(BIO_s_mem()); 66 char *name = NULL, *header = NULL; 67 unsigned char *data = NULL; 68 long len; 69 const char *encoded = b64_pem_data[0].encoded; 70 71 if (!TEST_ptr(b) 72 || !TEST_true(BIO_printf(b, "-----BEGIN %s-----\n", pemtype)) 73 || !TEST_true(BIO_printf(b, "%c%s\n", '\t', encoded)) 74 || !TEST_true(BIO_printf(b, "-----END %s-----\n", pemtype)) 75 /* Expected to fail due to non-base64 character */ 76 || TEST_true(PEM_read_bio_ex(b, &name, &header, &data, &len, 77 PEM_FLAG_ONLY_B64))) { 78 BIO_free(b); 79 return 0; 80 } 81 BIO_free(b); 82 OPENSSL_free(name); 83 OPENSSL_free(header); 84 OPENSSL_free(data); 85 return 1; 86 } 87 88 static int test_cert_key_cert(void) 89 { 90 EVP_PKEY *key; 91 92 if (!TEST_ptr(key = load_pkey_pem(pemfile, NULL))) 93 return 0; 94 95 EVP_PKEY_free(key); 96 return 1; 97 } 98 99 static int test_empty_payload(void) 100 { 101 BIO *b; 102 static char *emptypay = 103 "-----BEGIN CERTIFICATE-----\n" 104 "-\n" /* Base64 EOF character */ 105 "-----END CERTIFICATE-----"; 106 char *name = NULL, *header = NULL; 107 unsigned char *data = NULL; 108 long len; 109 int ret = 0; 110 111 b = BIO_new_mem_buf(emptypay, strlen(emptypay)); 112 if (!TEST_ptr(b)) 113 return 0; 114 115 /* Expected to fail because the payload is empty */ 116 if (!TEST_false(PEM_read_bio_ex(b, &name, &header, &data, &len, 0))) 117 goto err; 118 119 ret = 1; 120 err: 121 OPENSSL_free(name); 122 OPENSSL_free(header); 123 OPENSSL_free(data); 124 BIO_free(b); 125 return ret; 126 } 127 128 static int test_protected_params(void) 129 { 130 BIO *b; 131 static char *protectedpay = 132 "-----BEGIN RSA PRIVATE KEY-----\n" 133 "Proc-Type: 4,ENCRYPTED\n" 134 "DEK-Info: AES-256-CBC,4A44448ED28992710556549B35100CEA\n" 135 "\n" 136 "Xw3INxKeH+rUUF57mjATpvj6zknVhedwrlRmRvnwlLv5wqIy5Ae4UVLPh7SUswfC\n" 137 "-----END RSA PRIVATE KEY-----\n"; 138 EVP_PKEY *pkey = NULL; 139 int ret = 0; 140 141 b = BIO_new_mem_buf(protectedpay, strlen(protectedpay)); 142 if (!TEST_ptr(b)) 143 return 0; 144 145 /* Expected to fail because we cannot decrypt protected PEM files */ 146 pkey = PEM_read_bio_Parameters(b, NULL); 147 if (!TEST_ptr_null(pkey)) 148 goto err; 149 150 ret = 1; 151 err: 152 EVP_PKEY_free(pkey); 153 BIO_free(b); 154 return ret; 155 } 156 157 int setup_tests(void) 158 { 159 if (!TEST_ptr(pemfile = test_get_argument(0))) 160 return 0; 161 ADD_ALL_TESTS(test_b64, OSSL_NELEM(b64_pem_data)); 162 ADD_TEST(test_invalid); 163 ADD_TEST(test_cert_key_cert); 164 ADD_TEST(test_empty_payload); 165 ADD_TEST(test_protected_params); 166 return 1; 167 } 168