CryptX
view release on metacpan or search on metacpan
src/ltc/misc/pbes/pbes2.c view on Meta::CPAN
};
static int s_pbes2_from_oid(const ltc_asn1_list *cipher_oid, const ltc_asn1_list *hmac_oid, pbes_properties *res)
{
unsigned int i;
for (i = 0; i < LTC_ARRAY_SIZE(s_pbes2_list); ++i) {
if (pk_oid_cmp_with_asn1(s_pbes2_list[i].oid, cipher_oid) == CRYPT_OK) {
*res = *s_pbes2_list[i].data;
break;
}
}
if (res->c == NULL) return CRYPT_INVALID_CIPHER;
if (hmac_oid != NULL) {
for (i = 0; i < LTC_ARRAY_SIZE(s_hmac_oid_names); ++i) {
if (pk_oid_cmp_with_asn1(s_hmac_oid_names[i].oid, hmac_oid) == CRYPT_OK) {
res->h = s_hmac_oid_names[i].id;
return CRYPT_OK;
}
}
return CRYPT_INVALID_HASH;
}
return CRYPT_OK;
}
/**
Extract PBES2 parameters
@param s The start of the sequence with potential PBES2 parameters
@param res Pointer to where the extracted parameters should be stored
@return CRYPT_OK on success
*/
int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res)
{
unsigned long klen;
ltc_asn1_list *lkdf, *lenc, *loptseq, *liter, *lhmac;
int err;
LTC_ARGCHK(s != NULL);
LTC_ARGCHK(res != NULL);
if ((err = pk_oid_cmp_with_asn1(s_oid_pbes2, s)) != CRYPT_OK) return err;
if (!LTC_ASN1_IS_TYPE(s->next, LTC_ASN1_SEQUENCE) ||
!LTC_ASN1_IS_TYPE(s->next->child, LTC_ASN1_SEQUENCE) ||
!LTC_ASN1_IS_TYPE(s->next->child->child, LTC_ASN1_OBJECT_IDENTIFIER) ||
!LTC_ASN1_IS_TYPE(s->next->child->child->next, LTC_ASN1_SEQUENCE) ||
!LTC_ASN1_IS_TYPE(s->next->child->next, LTC_ASN1_SEQUENCE) ||
!LTC_ASN1_IS_TYPE(s->next->child->next->child, LTC_ASN1_OBJECT_IDENTIFIER)) {
return CRYPT_INVALID_PACKET;
}
/* PBES2: encrypted pkcs8 - PBES2+PBKDF2+des-ede3-cbc:
* 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 :PBES2 (== 1.2.840.113549.1.5.13) (== *s)
* 17:d=2 hl=2 l= 65 cons: SEQUENCE
* 19:d=3 hl=2 l= 41 cons: SEQUENCE
* 21:d=4 hl=2 l= 9 prim: OBJECT :PBKDF2 (== *lkdf)
* 32:d=4 hl=2 l= 28 cons: SEQUENCE
* 34:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:28BA4ABF6AA76A3D (== res->salt)
* 44:d=5 hl=2 l= 2 prim: INTEGER :0800 (== res->iterations, *liter)
* 48:d=5 hl=2 l= 12 cons: SEQUENCE (== *loptseq - this sequence is optional, may be missing)
* 50:d=6 hl=2 l= 8 prim: OBJECT :hmacWithSHA256 (== *lhmac)
* 60:d=6 hl=2 l= 0 prim: NULL
* 62:d=3 hl=2 l= 20 cons: SEQUENCE
* 64:d=4 hl=2 l= 8 prim: OBJECT :des-ede3-cbc (== *lenc)
* 74:d=4 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:B1404C4688DC9A5A
* 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data)
*/
lkdf = s->next->child->child;
lenc = s->next->child->next->child;
if ((err = pk_oid_cmp_with_asn1(s_oid_pbkdf2, lkdf)) != CRYPT_OK) return err;
if (!LTC_ASN1_IS_TYPE(lkdf->next, LTC_ASN1_SEQUENCE) ||
!LTC_ASN1_IS_TYPE(lkdf->next->child, LTC_ASN1_OCTET_STRING) ||
!LTC_ASN1_IS_TYPE(lkdf->next->child->next, LTC_ASN1_INTEGER)) {
return CRYPT_INVALID_PACKET;
}
liter = lkdf->next->child->next;
loptseq = liter->next;
res->salt = lkdf->next->child;
res->iterations = ltc_mp_get_int(liter->data);
/* There's an optional INTEGER keyLength after the iterations, skip that if it's there.
* c.f. RFC 2898 A.2 PBKDF2 */
if(LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_INTEGER)) {
loptseq = loptseq->next;
}
/* this sequence is optional */
lhmac = NULL;
if (LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_SEQUENCE) &&
LTC_ASN1_IS_TYPE(loptseq->child, LTC_ASN1_OBJECT_IDENTIFIER)) {
lhmac = loptseq->child;
}
if ((err = s_pbes2_from_oid(lenc, lhmac, &res->type)) != CRYPT_OK) return err;
if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_OCTET_STRING)) {
/* 'NON-RC2'-CBC */
res->iv = lenc->next;
} else if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_SEQUENCE)) {
/* RC2-CBC is a bit special ...
*
* RC2-CBC-Parameter ::= SEQUENCE {
* rc2ParameterVersion INTEGER OPTIONAL,
* iv OCTET STRING (SIZE(8)) }
*/
if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_INTEGER) &&
LTC_ASN1_IS_TYPE(lenc->next->child->next, LTC_ASN1_OCTET_STRING)) {
klen = ltc_mp_get_int(lenc->next->child->data);
res->iv = lenc->next->child->next;
/*
* Effective Key Bits Encoding
* 40 160
* 64 120
* 128 58
* b >= 256 b
*/
switch (klen) {
case 160:
res->key_bits = 40;
break;
case 120:
res->key_bits = 64;
break;
case 58:
res->key_bits = 128;
break;
default:
/* We don't handle undefined Key Bits */
if (klen < 256) return CRYPT_INVALID_KEYSIZE;
res->key_bits = klen;
break;
}
} else if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_OCTET_STRING)) {
res->iv = lenc->next->child;
/*
* If the rc2ParameterVersion field is omitted, the "effective key bits"
* defaults to 32.
*/
res->key_bits = 32;
} else {
return CRYPT_INVALID_PACKET;
( run in 0.961 second using v1.01-cache-2.11-cpan-71847e10f99 )