Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pgp/pgp_builder.c, revision 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>