1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 12e1051a39Sopenharmony_ci#include <openssl/pkcs12.h> 13e1051a39Sopenharmony_ci#include <openssl/trace.h> 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_ci/* 16e1051a39Sopenharmony_ci * Encrypt/Decrypt a buffer based on password and algor, result in a 17e1051a39Sopenharmony_ci * OPENSSL_malloc'ed buffer 18e1051a39Sopenharmony_ci */ 19e1051a39Sopenharmony_ciunsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor, 20e1051a39Sopenharmony_ci const char *pass, int passlen, 21e1051a39Sopenharmony_ci const unsigned char *in, int inlen, 22e1051a39Sopenharmony_ci unsigned char **data, int *datalen, int en_de, 23e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 24e1051a39Sopenharmony_ci{ 25e1051a39Sopenharmony_ci unsigned char *out = NULL; 26e1051a39Sopenharmony_ci int outlen, i; 27e1051a39Sopenharmony_ci EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); 28e1051a39Sopenharmony_ci int max_out_len, mac_len = 0; 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci if (ctx == NULL) { 31e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 32e1051a39Sopenharmony_ci goto err; 33e1051a39Sopenharmony_ci } 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_ci /* Process data */ 36e1051a39Sopenharmony_ci if (!EVP_PBE_CipherInit_ex(algor->algorithm, pass, passlen, 37e1051a39Sopenharmony_ci algor->parameter, ctx, en_de, libctx, propq)) 38e1051a39Sopenharmony_ci goto err; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci /* 41e1051a39Sopenharmony_ci * GOST algorithm specifics: 42e1051a39Sopenharmony_ci * OMAC algorithm calculate and encrypt MAC of the encrypted objects 43e1051a39Sopenharmony_ci * It's appended to encrypted text on encrypting 44e1051a39Sopenharmony_ci * MAC should be processed on decrypting separately from plain text 45e1051a39Sopenharmony_ci */ 46e1051a39Sopenharmony_ci max_out_len = inlen + EVP_CIPHER_CTX_get_block_size(ctx); 47e1051a39Sopenharmony_ci if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) 48e1051a39Sopenharmony_ci & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) { 49e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) < 0) { 50e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); 51e1051a39Sopenharmony_ci goto err; 52e1051a39Sopenharmony_ci } 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 55e1051a39Sopenharmony_ci max_out_len += mac_len; 56e1051a39Sopenharmony_ci } else { 57e1051a39Sopenharmony_ci if (inlen < mac_len) { 58e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNSUPPORTED_PKCS12_MODE); 59e1051a39Sopenharmony_ci goto err; 60e1051a39Sopenharmony_ci } 61e1051a39Sopenharmony_ci inlen -= mac_len; 62e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 63e1051a39Sopenharmony_ci (int)mac_len, (unsigned char *)in+inlen) < 0) { 64e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); 65e1051a39Sopenharmony_ci goto err; 66e1051a39Sopenharmony_ci } 67e1051a39Sopenharmony_ci } 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci if ((out = OPENSSL_malloc(max_out_len)) == NULL) { 71e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 72e1051a39Sopenharmony_ci goto err; 73e1051a39Sopenharmony_ci } 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci if (!EVP_CipherUpdate(ctx, out, &i, in, inlen)) { 76e1051a39Sopenharmony_ci OPENSSL_free(out); 77e1051a39Sopenharmony_ci out = NULL; 78e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_EVP_LIB); 79e1051a39Sopenharmony_ci goto err; 80e1051a39Sopenharmony_ci } 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci outlen = i; 83e1051a39Sopenharmony_ci if (!EVP_CipherFinal_ex(ctx, out + i, &i)) { 84e1051a39Sopenharmony_ci OPENSSL_free(out); 85e1051a39Sopenharmony_ci out = NULL; 86e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR, 87e1051a39Sopenharmony_ci passlen == 0 ? "empty password" 88e1051a39Sopenharmony_ci : "maybe wrong password"); 89e1051a39Sopenharmony_ci goto err; 90e1051a39Sopenharmony_ci } 91e1051a39Sopenharmony_ci outlen += i; 92e1051a39Sopenharmony_ci if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) 93e1051a39Sopenharmony_ci & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) { 94e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 95e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 96e1051a39Sopenharmony_ci (int)mac_len, out+outlen) < 0) { 97e1051a39Sopenharmony_ci OPENSSL_free(out); 98e1051a39Sopenharmony_ci out = NULL; 99e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); 100e1051a39Sopenharmony_ci goto err; 101e1051a39Sopenharmony_ci } 102e1051a39Sopenharmony_ci outlen += mac_len; 103e1051a39Sopenharmony_ci } 104e1051a39Sopenharmony_ci } 105e1051a39Sopenharmony_ci if (datalen) 106e1051a39Sopenharmony_ci *datalen = outlen; 107e1051a39Sopenharmony_ci if (data) 108e1051a39Sopenharmony_ci *data = out; 109e1051a39Sopenharmony_ci err: 110e1051a39Sopenharmony_ci EVP_CIPHER_CTX_free(ctx); 111e1051a39Sopenharmony_ci return out; 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci} 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ciunsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, 116e1051a39Sopenharmony_ci const char *pass, int passlen, 117e1051a39Sopenharmony_ci const unsigned char *in, int inlen, 118e1051a39Sopenharmony_ci unsigned char **data, int *datalen, int en_de) 119e1051a39Sopenharmony_ci{ 120e1051a39Sopenharmony_ci return PKCS12_pbe_crypt_ex(algor, pass, passlen, in, inlen, data, datalen, 121e1051a39Sopenharmony_ci en_de, NULL, NULL); 122e1051a39Sopenharmony_ci} 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ci/* 125e1051a39Sopenharmony_ci * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer 126e1051a39Sopenharmony_ci * after use. 127e1051a39Sopenharmony_ci */ 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_civoid *PKCS12_item_decrypt_d2i_ex(const X509_ALGOR *algor, const ASN1_ITEM *it, 130e1051a39Sopenharmony_ci const char *pass, int passlen, 131e1051a39Sopenharmony_ci const ASN1_OCTET_STRING *oct, int zbuf, 132e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, 133e1051a39Sopenharmony_ci const char *propq) 134e1051a39Sopenharmony_ci{ 135e1051a39Sopenharmony_ci unsigned char *out = NULL; 136e1051a39Sopenharmony_ci const unsigned char *p; 137e1051a39Sopenharmony_ci void *ret; 138e1051a39Sopenharmony_ci int outlen = 0; 139e1051a39Sopenharmony_ci 140e1051a39Sopenharmony_ci if (!PKCS12_pbe_crypt_ex(algor, pass, passlen, oct->data, oct->length, 141e1051a39Sopenharmony_ci &out, &outlen, 0, libctx, propq)) 142e1051a39Sopenharmony_ci return NULL; 143e1051a39Sopenharmony_ci p = out; 144e1051a39Sopenharmony_ci OSSL_TRACE_BEGIN(PKCS12_DECRYPT) { 145e1051a39Sopenharmony_ci BIO_printf(trc_out, "\n"); 146e1051a39Sopenharmony_ci BIO_dump(trc_out, out, outlen); 147e1051a39Sopenharmony_ci BIO_printf(trc_out, "\n"); 148e1051a39Sopenharmony_ci } OSSL_TRACE_END(PKCS12_DECRYPT); 149e1051a39Sopenharmony_ci ret = ASN1_item_d2i(NULL, &p, outlen, it); 150e1051a39Sopenharmony_ci if (zbuf) 151e1051a39Sopenharmony_ci OPENSSL_cleanse(out, outlen); 152e1051a39Sopenharmony_ci if (!ret) 153e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); 154e1051a39Sopenharmony_ci OPENSSL_free(out); 155e1051a39Sopenharmony_ci return ret; 156e1051a39Sopenharmony_ci} 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_civoid *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, 159e1051a39Sopenharmony_ci const char *pass, int passlen, 160e1051a39Sopenharmony_ci const ASN1_OCTET_STRING *oct, int zbuf) 161e1051a39Sopenharmony_ci{ 162e1051a39Sopenharmony_ci return PKCS12_item_decrypt_d2i_ex(algor, it, pass, passlen, oct, zbuf, 163e1051a39Sopenharmony_ci NULL, NULL); 164e1051a39Sopenharmony_ci} 165e1051a39Sopenharmony_ci 166e1051a39Sopenharmony_ci/* 167e1051a39Sopenharmony_ci * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero 168e1051a39Sopenharmony_ci * encoding. 169e1051a39Sopenharmony_ci */ 170e1051a39Sopenharmony_ci 171e1051a39Sopenharmony_ciASN1_OCTET_STRING *PKCS12_item_i2d_encrypt_ex(X509_ALGOR *algor, 172e1051a39Sopenharmony_ci const ASN1_ITEM *it, 173e1051a39Sopenharmony_ci const char *pass, int passlen, 174e1051a39Sopenharmony_ci void *obj, int zbuf, 175e1051a39Sopenharmony_ci OSSL_LIB_CTX *ctx, 176e1051a39Sopenharmony_ci const char *propq) 177e1051a39Sopenharmony_ci{ 178e1051a39Sopenharmony_ci ASN1_OCTET_STRING *oct = NULL; 179e1051a39Sopenharmony_ci unsigned char *in = NULL; 180e1051a39Sopenharmony_ci int inlen; 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci if ((oct = ASN1_OCTET_STRING_new()) == NULL) { 183e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 184e1051a39Sopenharmony_ci goto err; 185e1051a39Sopenharmony_ci } 186e1051a39Sopenharmony_ci inlen = ASN1_item_i2d(obj, &in, it); 187e1051a39Sopenharmony_ci if (!in) { 188e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR); 189e1051a39Sopenharmony_ci goto err; 190e1051a39Sopenharmony_ci } 191e1051a39Sopenharmony_ci if (!PKCS12_pbe_crypt_ex(algor, pass, passlen, in, inlen, &oct->data, 192e1051a39Sopenharmony_ci &oct->length, 1, ctx, propq)) { 193e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR); 194e1051a39Sopenharmony_ci OPENSSL_free(in); 195e1051a39Sopenharmony_ci goto err; 196e1051a39Sopenharmony_ci } 197e1051a39Sopenharmony_ci if (zbuf) 198e1051a39Sopenharmony_ci OPENSSL_cleanse(in, inlen); 199e1051a39Sopenharmony_ci OPENSSL_free(in); 200e1051a39Sopenharmony_ci return oct; 201e1051a39Sopenharmony_ci err: 202e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(oct); 203e1051a39Sopenharmony_ci return NULL; 204e1051a39Sopenharmony_ci} 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ciASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, 207e1051a39Sopenharmony_ci const ASN1_ITEM *it, 208e1051a39Sopenharmony_ci const char *pass, int passlen, 209e1051a39Sopenharmony_ci void *obj, int zbuf) 210e1051a39Sopenharmony_ci{ 211e1051a39Sopenharmony_ci return PKCS12_item_i2d_encrypt_ex(algor, it, pass, passlen, obj, zbuf, NULL, NULL); 212e1051a39Sopenharmony_ci} 213