1 /* 2 * Copyright 2018-2026 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 12 #include <openssl/pem.h> 13 #include <openssl/cms.h> 14 #include <openssl/bio.h> 15 #include <openssl/x509.h> 16 #include "../crypto/cms/cms_local.h" /* for d.signedData and d.envelopedData */ 17 18 #include "testutil.h" 19 20 static X509 *cert = NULL; 21 static EVP_PKEY *privkey = NULL; 22 static char *derin = NULL; 23 static char *too_long_iv_cms_in = NULL; 24 static char *pwri_kek_oob_der_in = NULL; 25 26 static int test_encrypt_decrypt(const EVP_CIPHER *cipher) 27 { 28 int testresult = 0; 29 STACK_OF(X509) *certstack = sk_X509_new_null(); 30 const char *msg = "Hello world"; 31 BIO *msgbio = BIO_new_mem_buf(msg, strlen(msg)); 32 BIO *outmsgbio = BIO_new(BIO_s_mem()); 33 CMS_ContentInfo *content = NULL; 34 BIO *contentbio = NULL; 35 char buf[80]; 36 37 if (!TEST_ptr(certstack) || !TEST_ptr(msgbio) || !TEST_ptr(outmsgbio)) 38 goto end; 39 40 if (!TEST_int_gt(sk_X509_push(certstack, cert), 0)) 41 goto end; 42 43 content = CMS_encrypt(certstack, msgbio, cipher, CMS_TEXT); 44 if (!TEST_ptr(content)) 45 goto end; 46 47 if (!TEST_true(CMS_decrypt(content, privkey, cert, NULL, outmsgbio, 48 CMS_TEXT))) 49 goto end; 50 51 if (!(EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) 52 && !TEST_ptr(contentbio = CMS_EnvelopedData_decrypt(content->d.envelopedData, 53 NULL, privkey, cert, NULL, 54 CMS_TEXT, NULL, NULL))) 55 goto end; 56 57 /* Check we got the message we first started with */ 58 if (!TEST_int_eq(BIO_gets(outmsgbio, buf, sizeof(buf)), strlen(msg)) 59 || !TEST_int_eq(strcmp(buf, msg), 0)) 60 goto end; 61 62 testresult = 1; 63 end: 64 BIO_free(contentbio); 65 sk_X509_free(certstack); 66 BIO_free(msgbio); 67 BIO_free(outmsgbio); 68 CMS_ContentInfo_free(content); 69 70 return testresult && TEST_int_eq(ERR_peek_error(), 0); 71 } 72 73 static int test_encrypt_decrypt_aes_cbc(void) 74 { 75 return test_encrypt_decrypt(EVP_aes_128_cbc()); 76 } 77 78 static int test_encrypt_decrypt_aes_128_gcm(void) 79 { 80 return test_encrypt_decrypt(EVP_aes_128_gcm()); 81 } 82 83 static int test_encrypt_decrypt_aes_192_gcm(void) 84 { 85 return test_encrypt_decrypt(EVP_aes_192_gcm()); 86 } 87 88 static int test_encrypt_decrypt_aes_256_gcm(void) 89 { 90 return test_encrypt_decrypt(EVP_aes_256_gcm()); 91 } 92 93 static int test_CMS_add1_cert(void) 94 { 95 CMS_ContentInfo *cms = NULL; 96 int ret = 0; 97 98 ret = TEST_ptr(cms = CMS_ContentInfo_new()) 99 && TEST_ptr(CMS_add1_signer(cms, cert, privkey, NULL, 0)) 100 && TEST_true(CMS_add1_cert(cms, cert)); /* add cert again */ 101 102 CMS_ContentInfo_free(cms); 103 return ret; 104 } 105 106 static int test_d2i_CMS_bio_NULL(void) 107 { 108 BIO *bio, *content = NULL; 109 CMS_ContentInfo *cms = NULL; 110 unsigned int flags = CMS_NO_SIGNER_CERT_VERIFY; 111 int ret = 0; 112 113 /* 114 * Test data generated using: 115 * openssl cms -sign -md sha256 -signer ./test/certs/rootCA.pem -inkey \ 116 * ./test/certs/rootCA.key -nodetach -outform DER -in ./in.txt -out out.der \ 117 * -nosmimecap 118 */ 119 static const unsigned char cms_data[] = { 120 0x30, 0x82, 0x05, 0xc5, 0x06, 0x09, 0x2a, 0x86, 121 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 122 0x82, 0x05, 0xb6, 0x30, 0x82, 0x05, 0xb2, 0x02, 123 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 124 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 125 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 126 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x0f, 127 0x04, 0x0d, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 128 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x0d, 0x0a, 0xa0, 129 0x82, 0x03, 0x83, 0x30, 0x82, 0x03, 0x7f, 0x30, 130 0x82, 0x02, 0x67, 0xa0, 0x03, 0x02, 0x01, 0x02, 131 0x02, 0x09, 0x00, 0x88, 0x43, 0x29, 0xcb, 0xc2, 132 0xeb, 0x15, 0x9a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 133 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 134 0x05, 0x00, 0x30, 0x56, 0x31, 0x0b, 0x30, 0x09, 135 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 136 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 137 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 138 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 139 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 140 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 141 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 142 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 143 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 144 0x04, 0x03, 0x0c, 0x06, 0x72, 0x6f, 0x6f, 0x74, 145 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 146 0x30, 0x37, 0x30, 0x32, 0x31, 0x33, 0x31, 0x35, 147 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 148 0x37, 0x30, 0x32, 0x31, 0x33, 0x31, 0x35, 0x31, 149 0x31, 0x5a, 0x30, 0x56, 0x31, 0x0b, 0x30, 0x09, 150 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 151 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 152 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 153 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 154 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 155 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 156 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 157 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 158 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 159 0x04, 0x03, 0x0c, 0x06, 0x72, 0x6f, 0x6f, 0x74, 160 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 161 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 162 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 163 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 164 0x01, 0x01, 0x00, 0xc0, 0xf1, 0x6b, 0x77, 0x88, 165 0xac, 0x35, 0xdf, 0xfb, 0x73, 0x53, 0x2f, 0x92, 166 0x80, 0x2f, 0x74, 0x16, 0x32, 0x4d, 0xf5, 0x10, 167 0x20, 0x6f, 0x6c, 0x3a, 0x8e, 0xd1, 0xdc, 0x6b, 168 0xe1, 0x2e, 0x3e, 0xc3, 0x04, 0x0f, 0xbf, 0x9b, 169 0xc4, 0xc9, 0x12, 0xd1, 0xe4, 0x0b, 0x45, 0x97, 170 0xe5, 0x06, 0xcd, 0x66, 0x3a, 0xe1, 0xe0, 0xe2, 171 0x2b, 0xdf, 0xa2, 0xc4, 0xec, 0x7b, 0xd3, 0x3d, 172 0x3c, 0x8a, 0xff, 0x5e, 0x74, 0xa0, 0xab, 0xa7, 173 0x03, 0x6a, 0x16, 0x5b, 0x5e, 0x92, 0xc4, 0x7e, 174 0x5b, 0x79, 0x8a, 0x69, 0xd4, 0xbc, 0x83, 0x5e, 175 0xae, 0x42, 0x92, 0x74, 0xa5, 0x2b, 0xe7, 0x00, 176 0xc1, 0xa9, 0xdc, 0xd5, 0xb1, 0x53, 0x07, 0x0f, 177 0x73, 0xf7, 0x8e, 0xad, 0x14, 0x3e, 0x25, 0x9e, 178 0xe5, 0x1e, 0xe6, 0xcc, 0x91, 0xcd, 0x95, 0x0c, 179 0x80, 0x44, 0x20, 0xc3, 0xfd, 0x17, 0xcf, 0x91, 180 0x3d, 0x63, 0x10, 0x1c, 0x14, 0x5b, 0xfb, 0xc3, 181 0xa8, 0xc1, 0x88, 0xb2, 0x77, 0xff, 0x9c, 0xdb, 182 0xfc, 0x6a, 0x44, 0x44, 0x44, 0xf7, 0x85, 0xec, 183 0x08, 0x2c, 0xd4, 0xdf, 0x81, 0xa3, 0x79, 0xc9, 184 0xfe, 0x1e, 0x9b, 0x93, 0x16, 0x53, 0xb7, 0x97, 185 0xab, 0xbe, 0x4f, 0x1a, 0xa5, 0xe2, 0xfa, 0x46, 186 0x05, 0xe4, 0x0d, 0x9c, 0x2a, 0xa4, 0xcc, 0xb9, 187 0x1e, 0x21, 0xa0, 0x6c, 0xc4, 0xab, 0x59, 0xb0, 188 0x40, 0x39, 0xbb, 0xf9, 0x88, 0xad, 0xfd, 0xdf, 189 0x8d, 0xb4, 0x0b, 0xaf, 0x7e, 0x41, 0xe0, 0x21, 190 0x3c, 0xc8, 0x33, 0x45, 0x49, 0x84, 0x2f, 0x93, 191 0x06, 0xee, 0xfd, 0x4f, 0xed, 0x4f, 0xf3, 0xbc, 192 0x9b, 0xde, 0xfc, 0x25, 0x5e, 0x55, 0xd5, 0x75, 193 0xd4, 0xc5, 0x7b, 0x3a, 0x40, 0x35, 0x06, 0x9f, 194 0xc4, 0x84, 0xb4, 0x6c, 0x93, 0x0c, 0xaf, 0x37, 195 0x5a, 0xaf, 0xb6, 0x41, 0x4d, 0x26, 0x23, 0x1c, 196 0xb8, 0x02, 0xb3, 0x02, 0x03, 0x01, 0x00, 0x01, 197 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 198 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 199 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 200 0x0e, 0x04, 0x16, 0x04, 0x14, 0x85, 0x56, 0x89, 201 0x35, 0xe2, 0x9f, 0x00, 0x1a, 0xe1, 0x86, 0x03, 202 0x0b, 0x4b, 0xaf, 0x76, 0x12, 0x6b, 0x33, 0x6d, 203 0xfd, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 204 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x85, 0x56, 205 0x89, 0x35, 0xe2, 0x9f, 0x00, 0x1a, 0xe1, 0x86, 206 0x03, 0x0b, 0x4b, 0xaf, 0x76, 0x12, 0x6b, 0x33, 207 0x6d, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 208 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 209 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x32, 0x0a, 210 0xbf, 0x2a, 0x0a, 0xe2, 0xbb, 0x4f, 0x43, 0xce, 211 0x88, 0xda, 0x5a, 0x39, 0x10, 0x37, 0x80, 0xbb, 212 0x37, 0x2d, 0x5e, 0x2d, 0x88, 0xdd, 0x26, 0x69, 213 0x9c, 0xe7, 0xb4, 0x98, 0x20, 0xb1, 0x25, 0xe6, 214 0x61, 0x59, 0x6d, 0x12, 0xec, 0x9b, 0x87, 0xbe, 215 0x57, 0xe1, 0x12, 0x05, 0xc5, 0x04, 0xf1, 0x17, 216 0xce, 0x14, 0xb8, 0x1c, 0x92, 0xd4, 0x95, 0x95, 217 0x2c, 0x5b, 0x28, 0x89, 0xfb, 0x72, 0x9c, 0x20, 218 0xd3, 0x32, 0x81, 0xa8, 0x85, 0xec, 0xc8, 0x08, 219 0x7b, 0xa8, 0x59, 0x5b, 0x3a, 0x6c, 0x31, 0xab, 220 0x52, 0xe2, 0x66, 0xcd, 0x14, 0x49, 0x5c, 0xf3, 221 0xd3, 0x3e, 0x62, 0xbc, 0x91, 0x16, 0xb4, 0x1c, 222 0xf5, 0xdd, 0x54, 0xaa, 0x3c, 0x61, 0x97, 0x79, 223 0xac, 0xe4, 0xc8, 0x43, 0x35, 0xc3, 0x0f, 0xfc, 224 0xf3, 0x70, 0x1d, 0xaf, 0xf0, 0x9c, 0x8a, 0x2a, 225 0x92, 0x93, 0x48, 0xaa, 0xd0, 0xe8, 0x47, 0xbe, 226 0x35, 0xc1, 0xc6, 0x7b, 0x6d, 0xda, 0xfa, 0x5d, 227 0x57, 0x45, 0xf3, 0xea, 0x41, 0x8f, 0x36, 0xc1, 228 0x3c, 0xf4, 0x52, 0x7f, 0x6e, 0x31, 0xdd, 0xba, 229 0x9a, 0xbc, 0x70, 0x56, 0x71, 0x38, 0xdc, 0x49, 230 0x57, 0x0c, 0xfd, 0x91, 0x17, 0xc5, 0xea, 0x87, 231 0xe5, 0x23, 0x74, 0x19, 0xb2, 0xb6, 0x99, 0x0c, 232 0x6b, 0xa2, 0x05, 0xf8, 0x51, 0x68, 0xed, 0x97, 233 0xe0, 0xdf, 0x62, 0xf9, 0x7e, 0x7a, 0x3a, 0x44, 234 0x71, 0x83, 0x57, 0x28, 0x49, 0x88, 0x69, 0xb5, 235 0x14, 0x1e, 0xda, 0x46, 0xe3, 0x6e, 0x78, 0xe1, 236 0xcb, 0x8f, 0xb5, 0x98, 0xb3, 0x2d, 0x6e, 0x5b, 237 0xb7, 0xf6, 0x93, 0x24, 0x14, 0x1f, 0xa4, 0xf6, 238 0x69, 0xbd, 0xff, 0x4c, 0x52, 0x50, 0x02, 0xc5, 239 0x43, 0x8d, 0x14, 0xe2, 0xd0, 0x75, 0x9f, 0x12, 240 0x5e, 0x94, 0x89, 0xd1, 0xef, 0x77, 0x89, 0x7d, 241 0x89, 0xd9, 0x9e, 0x76, 0x99, 0x24, 0x31, 0x82, 242 0x01, 0xf7, 0x30, 0x82, 0x01, 0xf3, 0x02, 0x01, 243 0x01, 0x30, 0x63, 0x30, 0x56, 0x31, 0x0b, 0x30, 244 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 245 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 246 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 247 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 248 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 249 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 250 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 251 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 252 0x74, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 253 0x55, 0x04, 0x03, 0x0c, 0x06, 0x72, 0x6f, 0x6f, 254 0x74, 0x43, 0x41, 0x02, 0x09, 0x00, 0x88, 0x43, 255 0x29, 0xcb, 0xc2, 0xeb, 0x15, 0x9a, 0x30, 0x0b, 256 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 257 0x04, 0x02, 0x01, 0xa0, 0x69, 0x30, 0x18, 0x06, 258 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 259 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 260 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 261 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 262 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 263 0x32, 0x30, 0x31, 0x32, 0x31, 0x31, 0x30, 0x39, 264 0x30, 0x30, 0x31, 0x33, 0x5a, 0x30, 0x2f, 0x06, 265 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 266 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0xb0, 0x80, 267 0x22, 0xd3, 0x15, 0xcf, 0x1e, 0xb1, 0x2d, 0x26, 268 0x65, 0xbd, 0xed, 0x0e, 0x6a, 0xf4, 0x06, 0x53, 269 0xc0, 0xa0, 0xbe, 0x97, 0x52, 0x32, 0xfb, 0x49, 270 0xbc, 0xbd, 0x02, 0x1c, 0xfc, 0x36, 0x30, 0x0d, 271 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 272 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 273 0x00, 0x37, 0x44, 0x39, 0x08, 0xb2, 0x19, 0x52, 274 0x35, 0x9c, 0xd0, 0x67, 0x87, 0xae, 0xb8, 0x1c, 275 0x80, 0xf4, 0x03, 0x29, 0x2e, 0xe3, 0x76, 0x4a, 276 0xb0, 0x98, 0x10, 0x00, 0x9a, 0x30, 0xdb, 0x05, 277 0x28, 0x53, 0x34, 0x31, 0x14, 0xbd, 0x87, 0xb9, 278 0x4d, 0x45, 0x07, 0x97, 0xa3, 0x57, 0x0b, 0x7e, 279 0xd1, 0x67, 0xfb, 0x4e, 0x0f, 0x5b, 0x90, 0xb2, 280 0x6f, 0xe6, 0xce, 0x49, 0xdd, 0x72, 0x46, 0x71, 281 0x26, 0xa1, 0x1b, 0x98, 0x23, 0x7d, 0x69, 0x73, 282 0x84, 0xdc, 0xf9, 0xd2, 0x1c, 0x6d, 0xf6, 0xf5, 283 0x17, 0x49, 0x6e, 0x9d, 0x4d, 0xf1, 0xe2, 0x43, 284 0x29, 0x53, 0x55, 0xa5, 0x22, 0x1e, 0x89, 0x2c, 285 0xaf, 0xf2, 0x43, 0x47, 0xd5, 0xfa, 0xad, 0xe7, 286 0x89, 0x60, 0xbf, 0x96, 0x35, 0x6f, 0xc2, 0x99, 287 0xb7, 0x55, 0xc5, 0xe3, 0x04, 0x25, 0x1b, 0xf6, 288 0x7e, 0xf2, 0x2b, 0x14, 0xa9, 0x57, 0x96, 0xbe, 289 0xbd, 0x6e, 0x95, 0x44, 0x94, 0xbd, 0xaf, 0x9a, 290 0x6d, 0x77, 0x55, 0x5e, 0x6c, 0xf6, 0x32, 0x37, 291 0xec, 0xef, 0xe5, 0x81, 0xb0, 0xe3, 0x35, 0xc7, 292 0x86, 0xea, 0x47, 0x59, 0x38, 0xb6, 0x16, 0xfb, 293 0x1d, 0x10, 0x55, 0x48, 0xb1, 0x44, 0x33, 0xde, 294 0xf6, 0x29, 0xbe, 0xbf, 0xbc, 0x71, 0x3e, 0x49, 295 0xba, 0xe7, 0x9f, 0x4d, 0x6c, 0xfb, 0xec, 0xd2, 296 0xe0, 0x12, 0xa9, 0x7c, 0xc9, 0x9a, 0x7b, 0x85, 297 0x83, 0xb8, 0xca, 0xdd, 0xf6, 0xb7, 0x15, 0x75, 298 0x7b, 0x4a, 0x69, 0xcf, 0x0a, 0xc7, 0x80, 0x01, 299 0xe7, 0x94, 0x16, 0x7f, 0x8d, 0x3c, 0xfa, 0x1f, 300 0x05, 0x71, 0x76, 0x15, 0xb0, 0xf6, 0x61, 0x30, 301 0x58, 0x16, 0xbe, 0x1b, 0xd1, 0x93, 0xc4, 0x1a, 302 0x91, 0x0c, 0x48, 0xe2, 0x1c, 0x8e, 0xa5, 0xc5, 303 0xa7, 0x81, 0x44, 0x48, 0x3b, 0x10, 0xc2, 0x74, 304 0x07, 0xdf, 0xa8, 0xae, 0x57, 0xee, 0x7f, 0xe3, 305 0x6a 306 }; 307 308 ret = TEST_ptr(bio = BIO_new_mem_buf(cms_data, sizeof(cms_data))) 309 && TEST_ptr(cms = d2i_CMS_bio(bio, NULL)) 310 && TEST_true(CMS_verify(cms, NULL, NULL, NULL, NULL, flags)) 311 && TEST_ptr(content = CMS_SignedData_verify(cms->d.signedData, NULL, NULL, NULL, 312 NULL, NULL, flags, NULL, NULL)); 313 BIO_free(content); 314 CMS_ContentInfo_free(cms); 315 BIO_free(bio); 316 return ret && TEST_int_eq(ERR_peek_error(), 0); 317 } 318 319 static unsigned char *read_all(BIO *bio, long *p_len) 320 { 321 const int step = 256; 322 unsigned char *buf = NULL; 323 unsigned char *tmp = NULL; 324 int ret; 325 326 *p_len = 0; 327 for (;;) { 328 tmp = OPENSSL_realloc(buf, *p_len + step); 329 if (tmp == NULL) 330 break; 331 buf = tmp; 332 ret = BIO_read(bio, buf + *p_len, step); 333 if (ret < 0) 334 break; 335 336 if (LONG_MAX - ret < *p_len) 337 break; 338 339 *p_len += ret; 340 341 if (ret < step) 342 return buf; 343 } 344 345 /* Error */ 346 OPENSSL_free(buf); 347 *p_len = 0; 348 return NULL; 349 } 350 351 static int test_d2i_CMS_decode(const int idx) 352 { 353 BIO *bio = NULL; 354 CMS_ContentInfo *cms = NULL; 355 unsigned char *buf = NULL; 356 const unsigned char *tmp = NULL; 357 long buf_len = 0; 358 int ret = 0; 359 360 if (!TEST_ptr(bio = BIO_new_file(derin, "r"))) 361 goto end; 362 363 switch (idx) { 364 case 0: 365 if (!TEST_ptr(cms = d2i_CMS_bio(bio, NULL))) 366 goto end; 367 break; 368 case 1: 369 if (!TEST_ptr(buf = read_all(bio, &buf_len))) 370 goto end; 371 tmp = buf; 372 if (!TEST_ptr(cms = d2i_CMS_ContentInfo(NULL, &tmp, buf_len))) 373 goto end; 374 break; 375 } 376 377 if (!TEST_int_eq(ERR_peek_error(), 0)) 378 goto end; 379 380 ret = 1; 381 end: 382 CMS_ContentInfo_free(cms); 383 BIO_free(bio); 384 OPENSSL_free(buf); 385 386 return ret; 387 } 388 389 static int test_CMS_set1_key_mem_leak(void) 390 { 391 CMS_ContentInfo *cms; 392 unsigned char key[32] = { 0 }; 393 int ret = 0; 394 395 if (!TEST_ptr(cms = CMS_ContentInfo_new())) 396 return 0; 397 398 if (!TEST_true(CMS_EncryptedData_set1_key(cms, EVP_aes_256_cbc(), 399 key, 32))) 400 goto end; 401 402 if (!TEST_true(CMS_EncryptedData_set1_key(cms, EVP_aes_128_cbc(), 403 key, 16))) 404 goto end; 405 406 ret = 1; 407 end: 408 CMS_ContentInfo_free(cms); 409 return ret; 410 } 411 412 static int test_encrypted_data(void) 413 { 414 const char *msg = "Hello world"; 415 BIO *msgbio = BIO_new_mem_buf(msg, (int)strlen(msg)); 416 uint8_t key[16] = { 0 }; 417 size_t keylen = 16; 418 CMS_ContentInfo *cms; 419 BIO *decryptbio = BIO_new(BIO_s_mem()); 420 char buf[80]; 421 int ret = 0; 422 423 cms = CMS_EncryptedData_encrypt(msgbio, EVP_aes_128_cbc(), key, keylen, SMIME_BINARY); 424 if (!TEST_ptr(cms)) 425 goto end; 426 427 if (!TEST_true(CMS_EncryptedData_decrypt(cms, key, keylen, NULL, decryptbio, SMIME_BINARY))) 428 goto end; 429 430 /* Check we got the message we first started with */ 431 if (!TEST_int_eq(BIO_gets(decryptbio, buf, sizeof(buf)), (int)strlen(msg)) 432 || !TEST_int_eq(strcmp(buf, msg), 0)) 433 goto end; 434 435 ret = 1; 436 end: 437 CMS_ContentInfo_free(cms); 438 BIO_free(msgbio); 439 BIO_free(decryptbio); 440 return ret; 441 } 442 443 static int test_encrypted_data_aead(void) 444 { 445 const char *msg = "Hello world"; 446 BIO *msgbio = BIO_new_mem_buf(msg, (int)strlen(msg)); 447 uint8_t key[16] = { 0 }; 448 size_t keylen = 16; 449 CMS_ContentInfo *cms; 450 BIO *decryptbio = BIO_new(BIO_s_mem()); 451 int ret = 0; 452 453 cms = CMS_ContentInfo_new(); 454 if (!TEST_ptr(cms)) 455 goto end; 456 457 /* 458 * AEAD algorithms are not supported by the CMS EncryptedData so setting 459 * the cipher to AES GCM 128 will result in a failure 460 */ 461 if (!TEST_false(CMS_EncryptedData_set1_key(cms, EVP_aes_128_gcm(), key, keylen))) 462 goto end; 463 464 CMS_ContentInfo_free(cms); 465 cms = NULL; 466 467 /* 468 * AEAD algorithms are not supported by the CMS EncryptedData so setting 469 * the cipher to AES GCM 128 will result in a failure 470 */ 471 cms = CMS_EncryptedData_encrypt(msgbio, EVP_aes_128_gcm(), key, keylen, SMIME_BINARY); 472 if (!TEST_ptr_null(cms)) 473 goto end; 474 475 ret = 1; 476 477 end: 478 CMS_ContentInfo_free(cms); 479 BIO_free(msgbio); 480 BIO_free(decryptbio); 481 return ret; 482 } 483 484 static int test_cms_aesgcm_iv_too_long(void) 485 { 486 int ret = 0; 487 BIO *cmsbio = NULL, *out = NULL; 488 CMS_ContentInfo *cms = NULL; 489 unsigned long err = 0; 490 491 if (!TEST_ptr(cmsbio = BIO_new_file(too_long_iv_cms_in, "r"))) 492 goto end; 493 494 if (!TEST_ptr(cms = PEM_read_bio_CMS(cmsbio, NULL, NULL, NULL))) 495 goto end; 496 497 /* Must fail cleanly (no crash) */ 498 if (!TEST_false(CMS_decrypt(cms, privkey, cert, NULL, out, 0))) 499 goto end; 500 err = ERR_peek_last_error(); 501 if (!TEST_ulong_ne(err, 0)) 502 goto end; 503 if (!TEST_int_eq(ERR_GET_LIB(err), ERR_LIB_CMS)) 504 goto end; 505 if (!TEST_int_eq(ERR_GET_REASON(err), CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR)) 506 goto end; 507 508 ret = 1; 509 end: 510 CMS_ContentInfo_free(cms); 511 BIO_free(cmsbio); 512 BIO_free(out); 513 return ret; 514 } 515 516 /* 517 * CMS EnvelopedData with a single PasswordRecipientInfo using 518 * id-alg-PWRI-KEK and an AES-128-CFB key encryption cipher 519 * (1-byte effective block size). The encryptedKey OCTET STRING is 520 * only two bytes long, so the wrapped key buffer is shorter than 521 * the seven octets read by the check-byte test in kek_unwrap_key(). 522 * Prior to CVE-2026-9076 this triggered an out-of-bounds heap read; 523 * CMS_decrypt() must now fail cleanly. 524 */ 525 static int test_pwri_kek_unwrap_short_encrypted_key(void) 526 { 527 BIO *in = NULL; 528 CMS_ContentInfo *cms = NULL; 529 unsigned long err = 0; 530 int ret = 0; 531 532 if (!TEST_ptr(in = BIO_new_file(pwri_kek_oob_der_in, "rb")) 533 || !TEST_ptr(cms = d2i_CMS_bio(in, NULL))) 534 goto end; 535 536 /* 537 * The unwrap is attempted eagerly inside CMS_decrypt_set1_password(). 538 * It must fail cleanly (no OOB read) and report CMS_R_UNWRAP_FAILURE. 539 */ 540 if (!TEST_false(CMS_decrypt_set1_password(cms, 541 (unsigned char *)"password", -1))) 542 goto end; 543 544 err = ERR_peek_last_error(); 545 if (!TEST_int_eq(ERR_GET_LIB(err), ERR_LIB_CMS) 546 || !TEST_int_eq(ERR_GET_REASON(err), CMS_R_UNWRAP_FAILURE)) 547 goto end; 548 549 ERR_clear_error(); 550 ret = 1; 551 end: 552 CMS_ContentInfo_free(cms); 553 BIO_free(in); 554 return ret; 555 } 556 557 OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile tooLongIVpem pwriKekOobDer\n") 558 559 int setup_tests(void) 560 { 561 char *certin = NULL, *privkeyin = NULL; 562 BIO *certbio = NULL, *privkeybio = NULL; 563 564 if (!test_skip_common_options()) { 565 TEST_error("Error parsing test options\n"); 566 return 0; 567 } 568 569 if (!TEST_ptr(certin = test_get_argument(0)) 570 || !TEST_ptr(privkeyin = test_get_argument(1)) 571 || !TEST_ptr(derin = test_get_argument(2)) 572 || !TEST_ptr(too_long_iv_cms_in = test_get_argument(3)) 573 || !TEST_ptr(pwri_kek_oob_der_in = test_get_argument(4))) 574 return 0; 575 576 certbio = BIO_new_file(certin, "r"); 577 if (!TEST_ptr(certbio)) 578 return 0; 579 if (!TEST_true(PEM_read_bio_X509(certbio, &cert, NULL, NULL))) { 580 BIO_free(certbio); 581 return 0; 582 } 583 BIO_free(certbio); 584 585 privkeybio = BIO_new_file(privkeyin, "r"); 586 if (!TEST_ptr(privkeybio)) { 587 X509_free(cert); 588 cert = NULL; 589 return 0; 590 } 591 if (!TEST_true(PEM_read_bio_PrivateKey(privkeybio, &privkey, NULL, NULL))) { 592 BIO_free(privkeybio); 593 X509_free(cert); 594 cert = NULL; 595 return 0; 596 } 597 BIO_free(privkeybio); 598 599 ADD_TEST(test_encrypt_decrypt_aes_cbc); 600 ADD_TEST(test_encrypt_decrypt_aes_128_gcm); 601 ADD_TEST(test_encrypt_decrypt_aes_192_gcm); 602 ADD_TEST(test_encrypt_decrypt_aes_256_gcm); 603 ADD_TEST(test_CMS_add1_cert); 604 ADD_TEST(test_d2i_CMS_bio_NULL); 605 ADD_TEST(test_CMS_set1_key_mem_leak); 606 ADD_TEST(test_encrypted_data); 607 ADD_TEST(test_encrypted_data_aead); 608 ADD_ALL_TESTS(test_d2i_CMS_decode, 2); 609 ADD_TEST(test_cms_aesgcm_iv_too_long); 610 ADD_TEST(test_pwri_kek_unwrap_short_encrypted_key); 611 return 1; 612 } 613 614 void cleanup_tests(void) 615 { 616 X509_free(cert); 617 EVP_PKEY_free(privkey); 618 } 619