Annotation of embedaddon/strongswan/src/libstrongswan/crypto/pkcs5.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2012-2013 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "pkcs5.h"
                     17: 
                     18: #include <utils/debug.h>
                     19: #include <asn1/oid.h>
                     20: #include <asn1/asn1.h>
                     21: #include <asn1/asn1_parser.h>
                     22: #include <credentials/containers/pkcs12.h>
                     23: 
                     24: typedef struct private_pkcs5_t private_pkcs5_t;
                     25: 
                     26: /**
                     27:  * Private data of a pkcs5_t object
                     28:  */
                     29: struct private_pkcs5_t {
                     30: 
                     31:        /**
                     32:         * Implements pkcs5_t.
                     33:         */
                     34:        pkcs5_t public;
                     35: 
                     36:        /**
                     37:         * Salt used during encryption
                     38:         */
                     39:        chunk_t salt;
                     40: 
                     41:        /**
                     42:         * Iterations for key derivation
                     43:         */
                     44:        uint64_t iterations;
                     45: 
                     46:        /**
                     47:         * Encryption algorithm
                     48:         */
                     49:        encryption_algorithm_t encr;
                     50: 
                     51:        /**
                     52:         * Encryption key length
                     53:         */
                     54:        size_t keylen;
                     55: 
                     56:        /**
                     57:         * Crypter
                     58:         */
                     59:        crypter_t *crypter;
                     60: 
                     61: 
                     62:        /**
                     63:         * The encryption scheme
                     64:         */
                     65:        enum {
                     66:                PKCS5_SCHEME_PBES1,
                     67:                PKCS5_SCHEME_PBES2,
                     68:                PKCS5_SCHEME_PKCS12,
                     69:        } scheme;
                     70: 
                     71:        /**
                     72:         * Data used for individual schemes
                     73:         */
                     74:        union {
                     75:                struct {
                     76:                        /**
                     77:                         * Hash algorithm
                     78:                         */
                     79:                        hash_algorithm_t hash;
                     80: 
                     81:                        /**
                     82:                         * Hasher
                     83:                         */
                     84:                        hasher_t *hasher;
                     85: 
                     86:                } pbes1;
                     87:                struct {
                     88:                        /**
                     89:                         * PRF algorithm
                     90:                         */
                     91:                        pseudo_random_function_t prf_alg;
                     92: 
                     93:                        /**
                     94:                         * PRF
                     95:                         */
                     96:                        prf_t * prf;
                     97: 
                     98:                        /**
                     99:                         * IV
                    100:                         */
                    101:                        chunk_t iv;
                    102: 
                    103:                } pbes2;
                    104:        } data;
                    105: };
                    106: 
                    107: /**
                    108:  * Verify padding of decrypted blob.
                    109:  * Length of blob is adjusted accordingly.
                    110:  */
                    111: static bool verify_padding(crypter_t *crypter, chunk_t *blob)
                    112: {
                    113:        uint8_t padding, count;
                    114: 
                    115:        padding = count = blob->ptr[blob->len - 1];
                    116: 
                    117:        if (padding > crypter->get_block_size(crypter))
                    118:        {
                    119:                return FALSE;
                    120:        }
                    121:        for (; blob->len && count; --blob->len, --count)
                    122:        {
                    123:                if (blob->ptr[blob->len - 1] != padding)
                    124:                {
                    125:                        return FALSE;
                    126:                }
                    127:        }
                    128:        return TRUE;
                    129: }
                    130: 
                    131: /**
                    132:  * Prototype for key derivation functions.
                    133:  */
                    134: typedef bool (*kdf_t)(private_pkcs5_t *this, chunk_t password, chunk_t key);
                    135: 
                    136: /**
                    137:  * Try to decrypt the given data with the given password using the given
                    138:  * key derivation function. keymat is where the kdf function writes the key
                    139:  * to, key and iv point to the actual keys and initialization vectors resp.
                    140:  */
                    141: static bool decrypt_generic(private_pkcs5_t *this, chunk_t password,
                    142:                                                        chunk_t data, chunk_t *decrypted, kdf_t kdf,
                    143:                                                        chunk_t keymat, chunk_t key, chunk_t iv)
                    144: {
                    145:        if (!kdf(this, password, keymat))
                    146:        {
                    147:                return FALSE;
                    148:        }
                    149:        if (!this->crypter->set_key(this->crypter, key) ||
                    150:                !this->crypter->decrypt(this->crypter, data, iv, decrypted))
                    151:        {
                    152:                memwipe(keymat.ptr, keymat.len);
                    153:                return FALSE;
                    154:        }
                    155:        memwipe(keymat.ptr, keymat.len);
                    156:        if (verify_padding(this->crypter, decrypted))
                    157:        {
                    158:                return TRUE;
                    159:        }
                    160:        chunk_free(decrypted);
                    161:        return FALSE;
                    162: }
                    163: 
                    164: /**
                    165:  * KDF as used by PKCS#12
                    166:  */
                    167: static bool pkcs12_kdf(private_pkcs5_t *this, chunk_t password, chunk_t keymat)
                    168: {
                    169:        chunk_t key, iv;
                    170: 
                    171:        key = chunk_create(keymat.ptr, this->keylen);
                    172:        iv = chunk_create(keymat.ptr + this->keylen, keymat.len - this->keylen);
                    173: 
                    174:        return pkcs12_derive_key(this->data.pbes1.hash, password, this->salt,
                    175:                                                         this->iterations, PKCS12_KEY_ENCRYPTION, key) &&
                    176:                   pkcs12_derive_key(this->data.pbes1.hash, password, this->salt,
                    177:                                                         this->iterations, PKCS12_KEY_IV, iv);
                    178: }
                    179: 
                    180: /**
                    181:  * Function F of PBKDF2
                    182:  */
                    183: static bool pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed,
                    184:                                         uint64_t iterations)
                    185: {
                    186:        chunk_t u;
                    187:        uint64_t i;
                    188: 
                    189:        u = chunk_alloca(prf->get_block_size(prf));
                    190:        if (!prf->get_bytes(prf, seed, u.ptr))
                    191:        {
                    192:                return FALSE;
                    193:        }
                    194:        memcpy(block.ptr, u.ptr, block.len);
                    195: 
                    196:        for (i = 1; i < iterations; i++)
                    197:        {
                    198:                if (!prf->get_bytes(prf, u, u.ptr))
                    199:                {
                    200:                        return FALSE;
                    201:                }
                    202:                memxor(block.ptr, u.ptr, block.len);
                    203:        }
                    204:        return TRUE;
                    205: }
                    206: 
                    207: /**
                    208:  * PBKDF2 key derivation function for PBES2, key must be allocated
                    209:  */
                    210: static bool pbkdf2(private_pkcs5_t *this, chunk_t password, chunk_t key)
                    211: {
                    212:        prf_t *prf;
                    213:        chunk_t keymat, block, seed;
                    214:        size_t blocks;
                    215:        uint32_t i = 0;
                    216: 
                    217:        prf = this->data.pbes2.prf;
                    218: 
                    219:        if (!prf->set_key(prf, password))
                    220:        {
                    221:                return FALSE;
                    222:        }
                    223: 
                    224:        block.len = prf->get_block_size(prf);
                    225:        blocks = (key.len - 1) / block.len + 1;
                    226:        keymat = chunk_alloca(blocks * block.len);
                    227: 
                    228:        seed = chunk_cata("cc", this->salt, chunk_from_thing(i));
                    229: 
                    230:        for (; i < blocks; i++)
                    231:        {
                    232:                htoun32(seed.ptr + this->salt.len, i + 1);
                    233:                block.ptr = keymat.ptr + (i * block.len);
                    234:                if (!pbkdf2_f(block, prf, seed, this->iterations))
                    235:                {
                    236:                        return FALSE;
                    237:                }
                    238:        }
                    239:        memcpy(key.ptr, keymat.ptr, key.len);
                    240:        return TRUE;
                    241: }
                    242: 
                    243: /**
                    244:  * PBKDF1 key derivation function for PBES1, key must be allocated
                    245:  */
                    246: static bool pbkdf1(private_pkcs5_t *this, chunk_t password, chunk_t key)
                    247: {
                    248:        hasher_t *hasher;
                    249:        chunk_t hash;
                    250:        uint64_t i;
                    251: 
                    252:        hasher = this->data.pbes1.hasher;
                    253: 
                    254:        hash = chunk_alloca(hasher->get_hash_size(hasher));
                    255:        if (!hasher->get_hash(hasher, password, NULL) ||
                    256:                !hasher->get_hash(hasher, this->salt, hash.ptr))
                    257:        {
                    258:                return FALSE;
                    259:        }
                    260: 
                    261:        for (i = 1; i < this->iterations; i++)
                    262:        {
                    263:                if (!hasher->get_hash(hasher, hash, hash.ptr))
                    264:                {
                    265:                        return FALSE;
                    266:                }
                    267:        }
                    268:        memcpy(key.ptr, hash.ptr, key.len);
                    269:        return TRUE;
                    270: }
                    271: 
                    272: static bool ensure_crypto_primitives(private_pkcs5_t *this, chunk_t data)
                    273: {
                    274:        if (!this->crypter)
                    275:        {
                    276:                this->crypter = lib->crypto->create_crypter(lib->crypto, this->encr,
                    277:                                                                                                        this->keylen);
                    278:                if (!this->crypter)
                    279:                {
                    280:                        DBG1(DBG_ASN, "  %N encryption algorithm not available",
                    281:                                 encryption_algorithm_names, this->encr);
                    282:                        return FALSE;
                    283:                }
                    284:        }
                    285:        if (data.len % this->crypter->get_block_size(this->crypter))
                    286:        {
                    287:                DBG1(DBG_ASN, "  data size is not a multiple of block size");
                    288:                return FALSE;
                    289:        }
                    290:        switch (this->scheme)
                    291:        {
                    292:                case PKCS5_SCHEME_PBES1:
                    293:                {
                    294:                        if (!this->data.pbes1.hasher)
                    295:                        {
                    296:                                hasher_t *hasher;
                    297: 
                    298:                                hasher = lib->crypto->create_hasher(lib->crypto,
                    299:                                                                                                        this->data.pbes1.hash);
                    300:                                if (!hasher)
                    301:                                {
                    302:                                        DBG1(DBG_ASN, "  %N hash algorithm not available",
                    303:                                                 hash_algorithm_names, this->data.pbes1.hash);
                    304:                                        return  FALSE;
                    305:                                }
                    306:                                if (hasher->get_hash_size(hasher) < this->keylen)
                    307:                                {
                    308:                                        hasher->destroy(hasher);
                    309:                                        return FALSE;
                    310:                                }
                    311:                                this->data.pbes1.hasher = hasher;
                    312:                        }
                    313:                        break;
                    314:                }
                    315:                case PKCS5_SCHEME_PBES2:
                    316:                {
                    317:                        if (!this->data.pbes2.prf)
                    318:                        {
                    319:                                prf_t *prf;
                    320: 
                    321:                                prf = lib->crypto->create_prf(lib->crypto,
                    322:                                                                                          this->data.pbes2.prf_alg);
                    323:                                if (!prf)
                    324:                                {
                    325:                                        DBG1(DBG_ASN, "  %N prf algorithm not available",
                    326:                                                 pseudo_random_function_names,
                    327:                                                 this->data.pbes2.prf_alg);
                    328:                                        return FALSE;
                    329:                                }
                    330:                                this->data.pbes2.prf = prf;
                    331:                        }
                    332:                        break;
                    333:                }
                    334:                case PKCS5_SCHEME_PKCS12:
                    335:                        break;
                    336:        }
                    337:        return TRUE;
                    338: }
                    339: 
                    340: METHOD(pkcs5_t, decrypt, bool,
                    341:        private_pkcs5_t *this, chunk_t password, chunk_t data, chunk_t *decrypted)
                    342: {
                    343:        chunk_t keymat, key, iv;
                    344:        kdf_t kdf;
                    345: 
                    346:        if (!ensure_crypto_primitives(this, data) || !decrypted)
                    347:        {
                    348:                return FALSE;
                    349:        }
                    350:        kdf = pbkdf1;
                    351:        switch (this->scheme)
                    352:        {
                    353:                case PKCS5_SCHEME_PKCS12:
                    354:                        kdf = pkcs12_kdf;
                    355:                        /* fall-through */
                    356:                case PKCS5_SCHEME_PBES1:
                    357:                        keymat = chunk_alloca(this->keylen +
                    358:                                                                  this->crypter->get_iv_size(this->crypter));
                    359:                        key = chunk_create(keymat.ptr, this->keylen);
                    360:                        iv = chunk_create(keymat.ptr + this->keylen,
                    361:                                                          keymat.len - this->keylen);
                    362:                        break;
                    363:                case PKCS5_SCHEME_PBES2:
                    364:                        kdf = pbkdf2;
                    365:                        keymat = chunk_alloca(this->keylen);
                    366:                        key = keymat;
                    367:                        iv = this->data.pbes2.iv;
                    368:                        break;
                    369:                default:
                    370:                        return FALSE;
                    371:        }
                    372:        return decrypt_generic(this, password, data, decrypted, kdf,
                    373:                                                   keymat, key, iv);
                    374: }
                    375: 
                    376: /**
                    377:  * ASN.1 definition of a PBEParameter structure
                    378:  */
                    379: static const asn1Object_t pbeParameterObjects[] = {
                    380:        { 0, "PBEParameter",            ASN1_SEQUENCE,          ASN1_NONE       }, /* 0 */
                    381:        { 1,   "salt",                          ASN1_OCTET_STRING,      ASN1_BODY       }, /* 1 */
                    382:        { 1,   "iterationCount",        ASN1_INTEGER,           ASN1_BODY       }, /* 2 */
                    383:        { 0, "exit",                            ASN1_EOC,                       ASN1_EXIT       }
                    384: };
                    385: #define PBEPARAM_SALT                                  1
                    386: #define PBEPARAM_ITERATION_COUNT               2
                    387: 
                    388: /**
                    389:  * Parse a PBEParameter structure
                    390:  */
                    391: static bool parse_pbes1_params(private_pkcs5_t *this, chunk_t blob, int level0)
                    392: {
                    393:        asn1_parser_t *parser;
                    394:        chunk_t object;
                    395:        int objectID;
                    396:        bool success;
                    397: 
                    398:        parser = asn1_parser_create(pbeParameterObjects, blob);
                    399:        parser->set_top_level(parser, level0);
                    400: 
                    401:        while (parser->iterate(parser, &objectID, &object))
                    402:        {
                    403:                switch (objectID)
                    404:                {
                    405:                        case PBEPARAM_SALT:
                    406:                        {
                    407:                                this->salt = chunk_clone(object);
                    408:                                break;
                    409:                        }
                    410:                        case PBEPARAM_ITERATION_COUNT:
                    411:                        {
                    412:                                this->iterations = asn1_parse_integer_uint64(object);
                    413:                                break;
                    414:                        }
                    415:                }
                    416:        }
                    417:        success = parser->success(parser);
                    418:        parser->destroy(parser);
                    419:        return success;
                    420: }
                    421: 
                    422: /**
                    423:  * ASN.1 definition of a PBKDF2-params structure
                    424:  * The salt is actually a CHOICE and could be an AlgorithmIdentifier from
                    425:  * PBKDF2-SaltSources (but as per RFC 8018 that's for future versions).
                    426:  * The PRF algorithm is actually defined as DEFAULT and not OPTIONAL, but the
                    427:  * parser can't handle ASN1_DEF with SEQUENCEs.
                    428:  */
                    429: static const asn1Object_t pbkdf2ParamsObjects[] = {
                    430:        { 0, "PBKDF2-params",   ASN1_SEQUENCE,          ASN1_NONE                       }, /* 0 */
                    431:        { 1,   "salt",                  ASN1_OCTET_STRING,      ASN1_BODY                       }, /* 1 */
                    432:        { 1,   "iterationCount",ASN1_INTEGER,           ASN1_BODY                       }, /* 2 */
                    433:        { 1,   "keyLength",             ASN1_INTEGER,           ASN1_OPT|ASN1_BODY      }, /* 3 */
                    434:        { 1,   "end opt",               ASN1_EOC,                       ASN1_END                        }, /* 4 */
                    435:        { 1,   "prf",                   ASN1_SEQUENCE,          ASN1_OPT|ASN1_RAW       }, /* 5 */
                    436:        { 1,   "end opt",               ASN1_EOC,                       ASN1_END                        }, /* 6 */
                    437:        { 0, "exit",                    ASN1_EOC,                       ASN1_EXIT                       }
                    438: };
                    439: #define PBKDF2_SALT                                    1
                    440: #define PBKDF2_ITERATION_COUNT         2
                    441: #define PBKDF2_KEYLENGTH                       3
                    442: #define PBKDF2_PRF                                     5
                    443: 
                    444: /**
                    445:  * Parse a PBKDF2-params structure
                    446:  */
                    447: static bool parse_pbkdf2_params(private_pkcs5_t *this, chunk_t blob, int level0)
                    448: {
                    449:        asn1_parser_t *parser;
                    450:        chunk_t object;
                    451:        int objectID;
                    452:        bool success = FALSE;
                    453: 
                    454:        parser = asn1_parser_create(pbkdf2ParamsObjects, blob);
                    455:        parser->set_top_level(parser, level0);
                    456: 
                    457:        /* keylen is optional */
                    458:        this->keylen = 0;
                    459:        /* defaults to id-hmacWithSHA1 */
                    460:        this->data.pbes2.prf_alg = PRF_HMAC_SHA1;
                    461: 
                    462:        while (parser->iterate(parser, &objectID, &object))
                    463:        {
                    464:                switch (objectID)
                    465:                {
                    466:                        case PBKDF2_SALT:
                    467:                        {
                    468:                                this->salt = chunk_clone(object);
                    469:                                break;
                    470:                        }
                    471:                        case PBKDF2_ITERATION_COUNT:
                    472:                        {
                    473:                                this->iterations = asn1_parse_integer_uint64(object);
                    474:                                break;
                    475:                        }
                    476:                        case PBKDF2_KEYLENGTH:
                    477:                        {
                    478:                                this->keylen = (size_t)asn1_parse_integer_uint64(object);
                    479:                                break;
                    480:                        }
                    481:                        case PBKDF2_PRF:
                    482:                        {
                    483:                                int oid;
                    484: 
                    485:                                oid = asn1_parse_algorithmIdentifier(object,
                    486:                                                                                parser->get_level(parser) + 1, NULL);
                    487:                                this->data.pbes2.prf_alg = pseudo_random_function_from_oid(oid);
                    488:                                if (this->data.pbes2.prf_alg == PRF_UNDEFINED)
                    489:                                {       /* unsupported PRF algorithm */
                    490:                                        goto end;
                    491:                                }
                    492:                                break;
                    493:                        }
                    494:                }
                    495:        }
                    496:        success = parser->success(parser);
                    497: end:
                    498:        parser->destroy(parser);
                    499:        return success;
                    500: }
                    501: 
                    502: /**
                    503:  * ASN.1 definition of a PBES2-params structure
                    504:  */
                    505: static const asn1Object_t pbes2ParamsObjects[] = {
                    506:        { 0, "PBES2-params",            ASN1_SEQUENCE,          ASN1_NONE       }, /* 0 */
                    507:        { 1,   "keyDerivationFunc",     ASN1_EOC,                       ASN1_RAW        }, /* 1 */
                    508:        { 1,   "encryptionScheme",      ASN1_EOC,                       ASN1_RAW        }, /* 2 */
                    509:        { 0, "exit",                            ASN1_EOC,                       ASN1_EXIT       }
                    510: };
                    511: #define PBES2PARAMS_KEY_DERIVATION_FUNC                1
                    512: #define PBES2PARAMS_ENCRYPTION_SCHEME          2
                    513: 
                    514: /**
                    515:  * Parse a PBES2-params structure
                    516:  */
                    517: static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
                    518: {
                    519:        asn1_parser_t *parser;
                    520:        chunk_t object, params;
                    521:        size_t keylen;
                    522:        int objectID;
                    523:        bool success = FALSE;
                    524: 
                    525:        parser = asn1_parser_create(pbes2ParamsObjects, blob);
                    526:        parser->set_top_level(parser, level0);
                    527: 
                    528:        while (parser->iterate(parser, &objectID, &object))
                    529:        {
                    530:                switch (objectID)
                    531:                {
                    532:                        case PBES2PARAMS_KEY_DERIVATION_FUNC:
                    533:                        {
                    534:                                int oid = asn1_parse_algorithmIdentifier(object,
                    535:                                                                        parser->get_level(parser) + 1, &params);
                    536:                                if (oid != OID_PBKDF2)
                    537:                                {       /* unsupported key derivation function */
                    538:                                        goto end;
                    539:                                }
                    540:                                if (!parse_pbkdf2_params(this, params,
                    541:                                                                                 parser->get_level(parser) + 1))
                    542:                                {
                    543:                                        goto end;
                    544:                                }
                    545:                                break;
                    546:                        }
                    547:                        case PBES2PARAMS_ENCRYPTION_SCHEME:
                    548:                        {
                    549:                                int oid = asn1_parse_algorithmIdentifier(object,
                    550:                                                                        parser->get_level(parser) + 1, &params);
                    551:                                this->encr = encryption_algorithm_from_oid(oid, &keylen);
                    552:                                if (this->encr == ENCR_UNDEFINED)
                    553:                                {       /* unsupported encryption scheme */
                    554:                                        goto end;
                    555:                                }
                    556:                                /* prefer encoded key length */
                    557:                                this->keylen = this->keylen ?: keylen / 8;
                    558:                                if (!this->keylen)
                    559:                                {       /* set default key length for known algorithms */
                    560:                                        switch (this->encr)
                    561:                                        {
                    562:                                                case ENCR_DES:
                    563:                                                        this->keylen = 8;
                    564:                                                        break;
                    565:                                                case ENCR_3DES:
                    566:                                                        this->keylen = 24;
                    567:                                                        break;
                    568:                                                case ENCR_BLOWFISH:
                    569:                                                        this->keylen = 16;
                    570:                                                        break;
                    571:                                                default:
                    572:                                                        goto end;
                    573:                                        }
                    574:                                }
                    575:                                if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING,
                    576:                                                                        parser->get_level(parser) + 1, "IV"))
                    577:                                {
                    578:                                        goto end;
                    579:                                }
                    580:                                this->data.pbes2.iv = chunk_clone(params);
                    581:                                break;
                    582:                        }
                    583:                }
                    584:        }
                    585:        success = parser->success(parser);
                    586: end:
                    587:        parser->destroy(parser);
                    588:        return success;
                    589: }
                    590: 
                    591: METHOD(pkcs5_t, destroy, void,
                    592:        private_pkcs5_t *this)
                    593: {
                    594:        DESTROY_IF(this->crypter);
                    595:        chunk_free(&this->salt);
                    596:        switch (this->scheme)
                    597:        {
                    598:                case PKCS5_SCHEME_PBES1:
                    599:                        DESTROY_IF(this->data.pbes1.hasher);
                    600:                        break;
                    601:                case PKCS5_SCHEME_PBES2:
                    602:                        DESTROY_IF(this->data.pbes2.prf);
                    603:                        chunk_free(&this->data.pbes2.iv);
                    604:                        break;
                    605:                case PKCS5_SCHEME_PKCS12:
                    606:                        break;
                    607:        }
                    608:        free(this);
                    609: }
                    610: 
                    611: /*
                    612:  * Described in header
                    613:  */
                    614: pkcs5_t *pkcs5_from_algorithmIdentifier(chunk_t blob, int level0)
                    615: {
                    616:        private_pkcs5_t *this;
                    617:        chunk_t params;
                    618:        int oid;
                    619: 
                    620:        INIT(this,
                    621:                .public = {
                    622:                        .decrypt = _decrypt,
                    623:                        .destroy = _destroy,
                    624:                },
                    625:                .scheme = PKCS5_SCHEME_PBES1,
                    626:                .keylen = 8,
                    627:        );
                    628: 
                    629:        oid = asn1_parse_algorithmIdentifier(blob, level0, &params);
                    630: 
                    631:        switch (oid)
                    632:        {
                    633:                case OID_PBE_MD5_DES_CBC:
                    634:                        this->encr = ENCR_DES;
                    635:                        this->data.pbes1.hash = HASH_MD5;
                    636:                        break;
                    637:                case OID_PBE_SHA1_DES_CBC:
                    638:                        this->encr = ENCR_DES;
                    639:                        this->data.pbes1.hash = HASH_SHA1;
                    640:                        break;
                    641:                case OID_PBE_SHA1_3DES_CBC:
                    642:                        this->scheme = PKCS5_SCHEME_PKCS12;
                    643:                        this->keylen = 24;
                    644:                        this->encr = ENCR_3DES;
                    645:                        this->data.pbes1.hash = HASH_SHA1;
                    646:                        break;
                    647:                case OID_PBE_SHA1_RC2_CBC_40:
                    648:                case OID_PBE_SHA1_RC2_CBC_128:
                    649:                        this->scheme = PKCS5_SCHEME_PKCS12;
                    650:                        this->keylen = (oid == OID_PBE_SHA1_RC2_CBC_40) ? 5 : 16;
                    651:                        this->encr = ENCR_RC2_CBC;
                    652:                        this->data.pbes1.hash = HASH_SHA1;
                    653:                        break;
                    654:                case OID_PBES2:
                    655:                        this->scheme = PKCS5_SCHEME_PBES2;
                    656:                        break;
                    657:                default:
                    658:                        /* encryption scheme not supported */
                    659:                        goto failure;
                    660:        }
                    661: 
                    662:        switch (this->scheme)
                    663:        {
                    664:                case PKCS5_SCHEME_PBES1:
                    665:                case PKCS5_SCHEME_PKCS12:
                    666:                        if (!parse_pbes1_params(this, params, level0))
                    667:                        {
                    668:                                goto failure;
                    669:                        }
                    670:                        break;
                    671:                case PKCS5_SCHEME_PBES2:
                    672:                        if (!parse_pbes2_params(this, params, level0))
                    673:                        {
                    674:                                goto failure;
                    675:                        }
                    676:                        break;
                    677:        }
                    678:        return &this->public;
                    679: 
                    680: failure:
                    681:        destroy(this);
                    682:        return NULL;
                    683: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>