Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2016 Tobias Brunner
                      3:  * Copyright (C) 2008-2009 Martin Willi
                      4:  * Copyright (C) 2000-2008 Andreas Steffen
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include "pkcs1_builder.h"
                     19: 
                     20: #include <utils/debug.h>
                     21: #include <asn1/oid.h>
                     22: #include <asn1/asn1.h>
                     23: #include <asn1/asn1_parser.h>
                     24: #include <credentials/keys/private_key.h>
                     25: 
                     26: /**
                     27:  * ASN.1 definition of a subjectPublicKeyInfo structure
                     28:  */
                     29: static const asn1Object_t pkinfoObjects[] = {
                     30:        { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE,              ASN1_NONE       }, /* 0 */
                     31:        { 1,   "algorithm",                     ASN1_EOC,                       ASN1_RAW        }, /* 1 */
                     32:        { 1,   "subjectPublicKey",      ASN1_BIT_STRING,        ASN1_BODY       }, /* 2 */
                     33:        { 0, "exit",                            ASN1_EOC,                       ASN1_EXIT       }
                     34: };
                     35: #define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM    1
                     36: #define PKINFO_SUBJECT_PUBLIC_KEY                      2
                     37: 
                     38: /**
                     39:  * Load a generic public key from an ASN.1 encoded blob
                     40:  */
                     41: static public_key_t *parse_public_key(chunk_t blob)
                     42: {
                     43:        asn1_parser_t *parser;
                     44:        chunk_t object;
                     45:        int objectID;
                     46:        public_key_t *key = NULL;
                     47:        key_type_t type = KEY_ANY;
                     48: 
                     49:        parser = asn1_parser_create(pkinfoObjects, blob);
                     50: 
                     51:        while (parser->iterate(parser, &objectID, &object))
                     52:        {
                     53:                switch (objectID)
                     54:                {
                     55:                        case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM:
                     56:                        {
                     57:                                int oid = asn1_parse_algorithmIdentifier(object,
                     58:                                                                                parser->get_level(parser)+1, NULL);
                     59: 
                     60:                                if (oid == OID_RSA_ENCRYPTION || oid == OID_RSAES_OAEP ||
                     61:                                        oid == OID_RSASSA_PSS)
                     62:                                {
                     63:                                        /* TODO: we should parse parameters for PSS and pass them
                     64:                                         * (and the type), or the complete subjectPublicKeyInfo,
                     65:                                         * along so we can treat these as restrictions when
                     66:                                         * generating signatures with the associated private key */
                     67:                                        type = KEY_RSA;
                     68:                                }
                     69:                                else if (oid == OID_EC_PUBLICKEY)
                     70:                                {
                     71:                                        /* Need the whole subjectPublicKeyInfo for EC public keys */
                     72:                                        key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
                     73:                                                                KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
                     74:                                        goto end;
                     75:                                }
                     76:                                else if (oid == OID_BLISS_PUBLICKEY)
                     77:                                {
                     78:                                        /* Need the whole subjectPublicKeyInfo for BLISS public keys */
                     79:                                        key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
                     80:                                                                KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
                     81:                                        goto end;
                     82:                                }
                     83:                                else if (oid == OID_ED25519)
                     84:                                {
                     85:                                        /* Need the whole subjectPublicKeyInfo for Ed25519 public keys */
                     86:                                        key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
                     87:                                                                KEY_ED25519, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
                     88:                                        goto end;
                     89:                                }
                     90:                                else if (oid == OID_ED448)
                     91:                                {
                     92:                                        /* Need the whole subjectPublicKeyInfo for Ed448 public keys */
                     93:                                        key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
                     94:                                                                KEY_ED448, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
                     95:                                        goto end;
                     96:                                }
                     97:                                else
                     98:                                {
                     99:                                        /* key type not supported */
                    100:                                        goto end;
                    101:                                }
                    102:                                break;
                    103:                        }
                    104:                        case PKINFO_SUBJECT_PUBLIC_KEY:
                    105:                                if (object.len > 0 && *object.ptr == 0x00)
                    106:                                {
                    107:                                        /* skip initial bit string octet defining 0 unused bits */
                    108:                                        object = chunk_skip(object, 1);
                    109:                                }
                    110:                                DBG2(DBG_ASN, "-- > --");
                    111:                                key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
                    112:                                                                                 BUILD_BLOB_ASN1_DER, object, BUILD_END);
                    113:                                DBG2(DBG_ASN, "-- < --");
                    114:                                break;
                    115:                }
                    116:        }
                    117: 
                    118: end:
                    119:        parser->destroy(parser);
                    120:        return key;
                    121: }
                    122: 
                    123: /**
                    124:  * ASN.1 definition of RSApublicKey
                    125:  */
                    126: static const asn1Object_t pubkeyObjects[] = {
                    127:        { 0, "RSAPublicKey",            ASN1_SEQUENCE,  ASN1_OBJ  }, /*  0 */
                    128:        { 1,   "modulus",                       ASN1_INTEGER,   ASN1_BODY }, /*  1 */
                    129:        { 1,   "publicExponent",        ASN1_INTEGER,   ASN1_BODY }, /*  2 */
                    130:        { 0, "exit",                            ASN1_EOC,               ASN1_EXIT }
                    131: };
                    132: #define PUB_KEY_RSA_PUBLIC_KEY         0
                    133: #define PUB_KEY_MODULUS                                1
                    134: #define PUB_KEY_EXPONENT                       2
                    135: 
                    136: /**
                    137:  * Load a RSA public key from an ASN.1 encoded blob.
                    138:  */
                    139: static public_key_t *parse_rsa_public_key(chunk_t blob)
                    140: {
                    141:        chunk_t n, e;
                    142:        asn1_parser_t *parser;
                    143:        chunk_t object;
                    144:        int objectID;
                    145:        bool success = FALSE;
                    146: 
                    147:        parser = asn1_parser_create(pubkeyObjects, blob);
                    148: 
                    149:        while (parser->iterate(parser, &objectID, &object))
                    150:        {
                    151:                switch (objectID)
                    152:                {
                    153:                        case PUB_KEY_MODULUS:
                    154:                                n = object;
                    155:                                break;
                    156:                        case PUB_KEY_EXPONENT:
                    157:                                e = object;
                    158:                                break;
                    159:                }
                    160:        }
                    161:        success = parser->success(parser);
                    162:        parser->destroy(parser);
                    163: 
                    164:        if (!success)
                    165:        {
                    166:                return NULL;
                    167:        }
                    168:        return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
                    169:                                                BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
                    170: }
                    171: 
                    172: /**
                    173:  * ASN.1 definition of a PKCS#1 RSA private key
                    174:  */
                    175: static const asn1Object_t privkeyObjects[] = {
                    176:        { 0, "RSAPrivateKey",           ASN1_SEQUENCE,     ASN1_NONE }, /*  0 */
                    177:        { 1,   "version",                       ASN1_INTEGER,      ASN1_BODY }, /*  1 */
                    178:        { 1,   "modulus",                       ASN1_INTEGER,      ASN1_BODY }, /*  2 */
                    179:        { 1,   "publicExponent",        ASN1_INTEGER,      ASN1_BODY }, /*  3 */
                    180:        { 1,   "privateExponent",       ASN1_INTEGER,      ASN1_BODY }, /*  4 */
                    181:        { 1,   "prime1",                        ASN1_INTEGER,      ASN1_BODY }, /*  5 */
                    182:        { 1,   "prime2",                        ASN1_INTEGER,      ASN1_BODY }, /*  6 */
                    183:        { 1,   "exponent1",                     ASN1_INTEGER,      ASN1_BODY }, /*  7 */
                    184:        { 1,   "exponent2",                     ASN1_INTEGER,      ASN1_BODY }, /*  8 */
                    185:        { 1,   "coefficient",           ASN1_INTEGER,      ASN1_BODY }, /*  9 */
                    186:        { 1,   "otherPrimeInfos",       ASN1_SEQUENCE,     ASN1_OPT |
                    187:                                                                                                   ASN1_LOOP }, /* 10 */
                    188:        { 2,     "otherPrimeInfo",      ASN1_SEQUENCE,     ASN1_NONE }, /* 11 */
                    189:        { 3,       "prime",                     ASN1_INTEGER,      ASN1_BODY }, /* 12 */
                    190:        { 3,       "exponent",          ASN1_INTEGER,      ASN1_BODY }, /* 13 */
                    191:        { 3,       "coefficient",       ASN1_INTEGER,      ASN1_BODY }, /* 14 */
                    192:        { 1,   "end opt or loop",       ASN1_EOC,          ASN1_END  }, /* 15 */
                    193:        { 0, "exit",                            ASN1_EOC,          ASN1_EXIT }
                    194: };
                    195: #define PRIV_KEY_VERSION                1
                    196: #define PRIV_KEY_MODULUS                2
                    197: #define PRIV_KEY_PUB_EXP                3
                    198: #define PRIV_KEY_PRIV_EXP               4
                    199: #define PRIV_KEY_PRIME1                         5
                    200: #define PRIV_KEY_PRIME2                         6
                    201: #define PRIV_KEY_EXP1                   7
                    202: #define PRIV_KEY_EXP2                   8
                    203: #define PRIV_KEY_COEFF                  9
                    204: 
                    205: /**
                    206:  * Load a RSA private key from a ASN1 encoded blob.
                    207:  */
                    208: static private_key_t *parse_rsa_private_key(chunk_t blob)
                    209: {
                    210:        chunk_t n, e, d, p, q, exp1, exp2, coeff;
                    211:        asn1_parser_t *parser;
                    212:        chunk_t object;
                    213:        int objectID ;
                    214:        bool success = FALSE;
                    215: 
                    216:        parser = asn1_parser_create(privkeyObjects, blob);
                    217:        parser->set_flags(parser, FALSE, TRUE);
                    218: 
                    219:        while (parser->iterate(parser, &objectID, &object))
                    220:        {
                    221:                switch (objectID)
                    222:                {
                    223:                        case PRIV_KEY_VERSION:
                    224:                                if (object.len > 0 && *object.ptr != 0)
                    225:                                {
                    226:                                        goto end;
                    227:                                }
                    228:                                break;
                    229:                        case PRIV_KEY_MODULUS:
                    230:                                n = object;
                    231:                                break;
                    232:                        case PRIV_KEY_PUB_EXP:
                    233:                                e = object;
                    234:                                break;
                    235:                        case PRIV_KEY_PRIV_EXP:
                    236:                                d = object;
                    237:                                break;
                    238:                        case PRIV_KEY_PRIME1:
                    239:                                p = object;
                    240:                                break;
                    241:                        case PRIV_KEY_PRIME2:
                    242:                                q = object;
                    243:                                break;
                    244:                        case PRIV_KEY_EXP1:
                    245:                                exp1 = object;
                    246:                                break;
                    247:                        case PRIV_KEY_EXP2:
                    248:                                exp2 = object;
                    249:                                break;
                    250:                        case PRIV_KEY_COEFF:
                    251:                                coeff = object;
                    252:                                break;
                    253:                }
                    254:        }
                    255:        success = parser->success(parser);
                    256: 
                    257: end:
                    258:        parser->destroy(parser);
                    259:        if (!success)
                    260:        {
                    261:                return NULL;
                    262:        }
                    263:        return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
                    264:                        BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_RSA_PRIV_EXP, d,
                    265:                        BUILD_RSA_PRIME1, p,  BUILD_RSA_PRIME2, q, BUILD_RSA_EXP1, exp1,
                    266:                        BUILD_RSA_EXP2, exp2, BUILD_RSA_COEFF, coeff, BUILD_END);
                    267: }
                    268: 
                    269: /**
                    270:  * Check if the ASN.1 structure looks like an EC private key according to
                    271:  * RFC 5915.
                    272:  *
                    273:  * ECPrivateKey :=: SEQUENCE {
                    274:  *   version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
                    275:  *   privateKey     OCTET STRING,
                    276:  *   parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
                    277:  *   publicKey  [1] BIT STRING OPTIONAL
                    278:  * }
                    279:  *
                    280:  * While the parameters and publicKey fields are OPTIONAL, RFC 5915 says that
                    281:  * parameters MUST be included (an errata clarifies this, so this is only the
                    282:  * case for plain private keys, not encoded in PKCS#8) and publicKey SHOULD be.
                    283:  */
                    284: static bool is_ec_private_key(chunk_t blob)
                    285: {
                    286:        chunk_t data;
                    287:        return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE &&
                    288:                   asn1_unwrap(&blob, &data) == ASN1_INTEGER &&
                    289:                   asn1_parse_integer_uint64(data) == 1 &&
                    290:                   asn1_unwrap(&blob, &data) == ASN1_OCTET_STRING &&
                    291:                   asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_0 &&
                    292:                   asn1_unwrap(&data, &data) == ASN1_OID &&
                    293:                   (!blob.len || (asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_1));
                    294: }
                    295: 
                    296: /**
                    297:  * Check if the ASN.1 structure looks like a BLISS private key.
                    298:  */
                    299: static bool is_bliss_private_key(chunk_t blob)
                    300: {
                    301:        chunk_t data;
                    302:        return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE &&
                    303:                   asn1_unwrap(&blob, &data) == ASN1_OID &&
                    304:                   asn1_unwrap(&blob, &data) == ASN1_BIT_STRING &&
                    305:                   asn1_unwrap(&blob, &data) == ASN1_BIT_STRING &&
                    306:                   asn1_unwrap(&blob, &data) == ASN1_BIT_STRING;
                    307: }
                    308: 
                    309: /**
                    310:  * Load a private key from an ASN.1 encoded blob trying to detect the type
                    311:  * automatically.
                    312:  */
                    313: static private_key_t *parse_private_key(chunk_t blob)
                    314: {
                    315:        if (is_ec_private_key(blob))
                    316:        {
                    317:                return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
                    318:                                                                  BUILD_BLOB_ASN1_DER, blob, BUILD_END);
                    319:        }
                    320:        else if (is_bliss_private_key(blob))
                    321:        {
                    322:                return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
                    323:                                                                  BUILD_BLOB_ASN1_DER, blob, BUILD_END);
                    324:        }
                    325:        return parse_rsa_private_key(blob);
                    326: }
                    327: 
                    328: /**
                    329:  * See header.
                    330:  */
                    331: public_key_t *pkcs1_public_key_load(key_type_t type, va_list args)
                    332: {
                    333:        chunk_t blob = chunk_empty;
                    334: 
                    335:        while (TRUE)
                    336:        {
                    337:                switch (va_arg(args, builder_part_t))
                    338:                {
                    339:                        case BUILD_BLOB_ASN1_DER:
                    340:                                blob = va_arg(args, chunk_t);
                    341:                                continue;
                    342:                        case BUILD_END:
                    343:                                break;
                    344:                        default:
                    345:                                return NULL;
                    346:                }
                    347:                break;
                    348:        }
                    349:        switch (type)
                    350:        {
                    351:                case KEY_ANY:
                    352:                        return parse_public_key(blob);
                    353:                case KEY_RSA:
                    354:                        return parse_rsa_public_key(blob);
                    355:                default:
                    356:                        return NULL;
                    357:        }
                    358: }
                    359: 
                    360: /**
                    361:  * See header.
                    362:  */
                    363: private_key_t *pkcs1_private_key_load(key_type_t type, va_list args)
                    364: {
                    365:        chunk_t blob = chunk_empty;
                    366: 
                    367:        while (TRUE)
                    368:        {
                    369:                switch (va_arg(args, builder_part_t))
                    370:                {
                    371:                        case BUILD_BLOB_ASN1_DER:
                    372:                                blob = va_arg(args, chunk_t);
                    373:                                continue;
                    374:                        case BUILD_END:
                    375:                                break;
                    376:                        default:
                    377:                                return NULL;
                    378:                }
                    379:                break;
                    380:        }
                    381:        switch (type)
                    382:        {
                    383:                case KEY_ANY:
                    384:                        return parse_private_key(blob);
                    385:                case KEY_RSA:
                    386:                        return parse_rsa_private_key(blob);
                    387:                default:
                    388:                        return NULL;
                    389:        }
                    390: }
                    391: 

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