Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pgp/pgp_builder.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2009 Martin Willi
                      3:  * Copyright (C) 2002-2009 Andreas Steffen
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include "pgp_builder.h"
                     18: #include "pgp_utils.h"
                     19: 
                     20: #include <utils/utils.h>
                     21: #include <utils/debug.h>
                     22: #include <credentials/keys/private_key.h>
                     23: 
                     24: /**
                     25:  * Load a generic public key from a PGP packet
                     26:  */
                     27: static public_key_t *parse_public_key(chunk_t blob)
                     28: {
                     29:        uint32_t alg;
                     30:        public_key_t *key;
                     31: 
                     32:        if (!pgp_read_scalar(&blob, 1, &alg))
                     33:        {
                     34:                return NULL;
                     35:        }
                     36:        switch (alg)
                     37:        {
                     38:                case PGP_PUBKEY_ALG_RSA:
                     39:                case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
                     40:                        key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
                     41:                                                                         BUILD_BLOB_PGP, blob, BUILD_END);
                     42:                        break;
                     43:                default:
                     44:                        DBG1(DBG_LIB, "PGP public key algorithm %N not supported",
                     45:                                 pgp_pubkey_alg_names, alg);
                     46:                        return NULL;
                     47:        }
                     48:        return key;
                     49: }
                     50: 
                     51: /**
                     52:  * Load a RSA public key from a PGP packet
                     53:  */
                     54: static public_key_t *parse_rsa_public_key(chunk_t blob)
                     55: {
                     56:        chunk_t mpi[2];
                     57:        int i;
                     58: 
                     59:        for (i = 0; i < 2; i++)
                     60:        {
                     61:                if (!pgp_read_mpi(&blob, &mpi[i]))
                     62:                {
                     63:                        return NULL;
                     64:                }
                     65:        }
                     66:        return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
                     67:                                                BUILD_RSA_MODULUS, mpi[0], BUILD_RSA_PUB_EXP, mpi[1],
                     68:                                                BUILD_END);
                     69: }
                     70: 
                     71: /**
                     72:  * Load a RSA private key from a PGP packet
                     73:  */
                     74: static private_key_t *parse_rsa_private_key(chunk_t blob)
                     75: {
                     76:        chunk_t mpi[6];
                     77:        uint32_t s2k;
                     78:        int i;
                     79: 
                     80:        for (i = 0; i < 2; i++)
                     81:        {
                     82:                if (!pgp_read_mpi(&blob, &mpi[i]))
                     83:                {
                     84:                        return NULL;
                     85:                }
                     86:        }
                     87:        if (!pgp_read_scalar(&blob, 1, &s2k))
                     88:        {
                     89:                return NULL;
                     90:        }
                     91:        if (s2k == 255 || s2k == 254)
                     92:        {
                     93:                DBG1(DBG_LIB, "string-to-key specifiers not supported");
                     94:                return NULL;
                     95:        }
                     96:        if (s2k != PGP_SYM_ALG_PLAIN)
                     97:        {
                     98:                DBG1(DBG_LIB, "%N private key encryption not supported",
                     99:                         pgp_sym_alg_names, s2k);
                    100:                return NULL;
                    101:        }
                    102: 
                    103:        for (i = 2; i < 6; i++)
                    104:        {
                    105:                if (!pgp_read_mpi(&blob, &mpi[i]))
                    106:                {
                    107:                        return NULL;
                    108:                }
                    109:        }
                    110: 
                    111:        /* PGP has uses p < q, but we use p > q */
                    112:        return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
                    113:                                                BUILD_RSA_MODULUS, mpi[0], BUILD_RSA_PUB_EXP, mpi[1],
                    114:                                                BUILD_RSA_PRIV_EXP, mpi[2], BUILD_RSA_PRIME2, mpi[3],
                    115:                                                BUILD_RSA_PRIME1, mpi[4], BUILD_RSA_COEFF, mpi[5],
                    116:                                                BUILD_END);
                    117: }
                    118: 
                    119: METHOD(private_key_t, sign_not_allowed, bool,
                    120:        private_key_t *this, signature_scheme_t scheme, void *params,
                    121:        chunk_t data, chunk_t *signature)
                    122: {
                    123:        DBG1(DBG_LIB, "signing failed - decryption only key");
                    124:        return FALSE;
                    125: }
                    126: 
                    127: METHOD(private_key_t, decrypt_not_allowed, bool,
                    128:        private_key_t *this, encryption_scheme_t scheme,
                    129:        chunk_t crypto, chunk_t *plain)
                    130: {
                    131:        DBG1(DBG_LIB, "decryption failed - signature only key");
                    132:        return FALSE;
                    133: }
                    134: 
                    135: /**
                    136:  * Load a generic private key from a PGP packet
                    137:  */
                    138: static private_key_t *parse_private_key(chunk_t blob)
                    139: {
                    140:        chunk_t packet;
                    141:        pgp_packet_tag_t tag;
                    142:        uint32_t version, created, days, alg;
                    143:        private_key_t *key;
                    144: 
                    145:        if (!pgp_read_packet(&blob, &packet, &tag))
                    146:        {
                    147:                return NULL;
                    148:        }
                    149:        if (!pgp_read_scalar(&packet, 1, &version))
                    150:        {
                    151:                return NULL;
                    152:        }
                    153:        switch (version)
                    154:        {
                    155:                case 3:
                    156:                        if (!pgp_read_scalar(&packet, 2, &days))
                    157:                        {
                    158:                                return NULL;
                    159:                        }
                    160:                        break;
                    161:                case 4:
                    162:                        break;
                    163:                default:
                    164:                        DBG1(DBG_LIB, "PGP packet version V%d not supported", version);
                    165:                        return NULL;
                    166:        }
                    167:        if (!pgp_read_scalar(&packet, 4, &created))
                    168:        {
                    169:                return NULL;
                    170:        }
                    171:        if (!pgp_read_scalar(&packet, 1, &alg))
                    172:        {
                    173:                return NULL;
                    174:        }
                    175:        switch (alg)
                    176:        {
                    177:                case PGP_PUBKEY_ALG_RSA:
                    178:                        return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
                    179:                                                                          BUILD_BLOB_PGP, packet, BUILD_END);
                    180:                case PGP_PUBKEY_ALG_RSA_ENC_ONLY:
                    181:                        key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
                    182:                                                                          BUILD_BLOB_PGP, packet, BUILD_END);
                    183:                        if (key)
                    184:                        {
                    185:                                key->sign = _sign_not_allowed;
                    186:                        }
                    187:                        return key;
                    188:                case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
                    189:                        key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
                    190:                                                                          BUILD_BLOB_PGP, packet, BUILD_END);
                    191:                        if (key)
                    192:                        {
                    193:                                key->decrypt = _decrypt_not_allowed;
                    194:                        }
                    195:                        return key;
                    196:                case PGP_PUBKEY_ALG_ECDSA:
                    197:                        return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
                    198:                                                                          BUILD_BLOB_PGP, packet, BUILD_END);
                    199:                case PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY:
                    200:                case PGP_PUBKEY_ALG_DSA:
                    201:                case PGP_PUBKEY_ALG_ECC:
                    202:                case PGP_PUBKEY_ALG_ELGAMAL:
                    203:                case PGP_PUBKEY_ALG_DIFFIE_HELLMAN:
                    204:                default:
                    205:                        return NULL;
                    206:        }
                    207: }
                    208: 
                    209: /**
                    210:  *  See header.
                    211:  */
                    212: public_key_t *pgp_public_key_load(key_type_t type, va_list args)
                    213: {
                    214:        chunk_t blob = chunk_empty;
                    215: 
                    216:        while (TRUE)
                    217:        {
                    218:                switch (va_arg(args, builder_part_t))
                    219:                {
                    220:                        case BUILD_BLOB_PGP:
                    221:                                blob = va_arg(args, chunk_t);
                    222:                                continue;
                    223:                        case BUILD_END:
                    224:                                break;
                    225:                        default:
                    226:                                return NULL;
                    227:                }
                    228:                break;
                    229:        }
                    230:        switch (type)
                    231:        {
                    232:                case KEY_ANY:
                    233:                        return parse_public_key(blob);
                    234:                case KEY_RSA:
                    235:                        return parse_rsa_public_key(blob);
                    236:                default:
                    237:                        return NULL;
                    238:        }
                    239: }
                    240: 
                    241: /**
                    242:  * See header.
                    243:  */
                    244: private_key_t *pgp_private_key_load(key_type_t type, va_list args)
                    245: {
                    246:        chunk_t blob = chunk_empty;
                    247: 
                    248:        while (TRUE)
                    249:        {
                    250:                switch (va_arg(args, builder_part_t))
                    251:                {
                    252:                        case BUILD_BLOB_PGP:
                    253:                                blob = va_arg(args, chunk_t);
                    254:                                continue;
                    255:                        case BUILD_END:
                    256:                                break;
                    257:                        default:
                    258:                                return NULL;
                    259:                }
                    260:                break;
                    261:        }
                    262:        switch (type)
                    263:        {
                    264:                case KEY_ANY:
                    265:                        return parse_private_key(blob);
                    266:                case KEY_RSA:
                    267:                        return parse_rsa_private_key(blob);
                    268:                default:
                    269:                        return NULL;
                    270:        }
                    271: }

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