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 )