Replaced system SQLite with SQLCipher to support encrypted database
This commit is contained in:
106
Sources/DataLiteC/libtomcrypt/pk/asn1/pkcs8/pkcs8_decode_flexi.c
Normal file
106
Sources/DataLiteC/libtomcrypt/pk/asn1/pkcs8/pkcs8_decode_flexi.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_PKCS_8
|
||||
|
||||
/**
|
||||
PKCS#8 decrypt if necessary & flexi-decode
|
||||
|
||||
@param in Pointer to the ASN.1 encoded input data
|
||||
@param inlen Length of the input data
|
||||
@param pwd Pointer to the password that was used when encrypting
|
||||
@param pwdlen Length of the password
|
||||
@param decoded_list Pointer to a pointer for the flexi-decoded list
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
|
||||
const password_ctx *pw_ctx,
|
||||
ltc_asn1_list **decoded_list)
|
||||
{
|
||||
unsigned long len = inlen;
|
||||
unsigned long dec_size;
|
||||
unsigned char *dec_data = NULL;
|
||||
ltc_asn1_list *l = NULL;
|
||||
int err;
|
||||
pbes_arg pbes;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(decoded_list != NULL);
|
||||
|
||||
XMEMSET(&pbes, 0, sizeof(pbes));
|
||||
|
||||
*decoded_list = NULL;
|
||||
if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) {
|
||||
/* the following "if" detects whether it is encrypted or not */
|
||||
/* PKCS8 Setup
|
||||
* 0:d=0 hl=4 l= 380 cons: SEQUENCE
|
||||
* 4:d=1 hl=2 l= 78 cons: SEQUENCE
|
||||
* 6:d=2 hl=2 l= 9 prim: OBJECT :OID indicating PBES1 or PBES2 (== *lalgoid)
|
||||
* 17:d=2 hl=2 l= 65 cons: SEQUENCE
|
||||
* Stuff in between is dependent on whether it's PBES1 or PBES2
|
||||
* 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data)
|
||||
*/
|
||||
if (l->type == LTC_ASN1_SEQUENCE &&
|
||||
LTC_ASN1_IS_TYPE(l->child, LTC_ASN1_SEQUENCE) &&
|
||||
LTC_ASN1_IS_TYPE(l->child->child, LTC_ASN1_OBJECT_IDENTIFIER) &&
|
||||
LTC_ASN1_IS_TYPE(l->child->child->next, LTC_ASN1_SEQUENCE) &&
|
||||
LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) {
|
||||
ltc_asn1_list *lalgoid = l->child->child;
|
||||
|
||||
if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
|
||||
err = CRYPT_PW_CTX_MISSING;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
if (pbes1_extract(lalgoid, &pbes) == CRYPT_OK) {
|
||||
/* Successfully extracted PBES1 parameters */
|
||||
} else if (pbes2_extract(lalgoid, &pbes) == CRYPT_OK) {
|
||||
/* Successfully extracted PBES2 parameters */
|
||||
} else {
|
||||
/* unsupported encryption */
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
if (pw_ctx->callback(&pbes.pw.pw, &pbes.pw.l, pw_ctx->userdata)) {
|
||||
err = CRYPT_ERROR;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
pbes.enc_data = l->child->next;
|
||||
|
||||
dec_size = pbes.enc_data->size;
|
||||
if ((dec_data = XMALLOC(dec_size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
if ((err = pbes_decrypt(&pbes, dec_data, &dec_size)) != CRYPT_OK) goto LBL_DONE;
|
||||
|
||||
der_free_sequence_flexi(l);
|
||||
l = NULL;
|
||||
err = der_decode_sequence_flexi(dec_data, &dec_size, &l);
|
||||
if (err != CRYPT_OK) goto LBL_DONE;
|
||||
*decoded_list = l;
|
||||
}
|
||||
else {
|
||||
/* not encrypted */
|
||||
err = CRYPT_OK;
|
||||
*decoded_list = l;
|
||||
}
|
||||
/* Set l to NULL so it won't be free'd */
|
||||
l = NULL;
|
||||
}
|
||||
|
||||
LBL_DONE:
|
||||
if (dec_data) {
|
||||
zeromem(dec_data, dec_size);
|
||||
XFREE(dec_data);
|
||||
}
|
||||
password_free(&pbes.pw, pw_ctx);
|
||||
if (l) der_free_sequence_flexi(l);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user