Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pgp/pgp_utils.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2009 Martin Willi
        !             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 "pgp_utils.h"
        !            17: 
        !            18: #include <utils/debug.h>
        !            19: 
        !            20: ENUM_BEGIN(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_RSA, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
        !            21:        "RSA",
        !            22:        "RSA_ENC_ONLY",
        !            23:        "RSA_SIGN_ONLY"
        !            24: );
        !            25: ENUM_NEXT(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY, PGP_PUBKEY_ALG_DIFFIE_HELLMAN, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
        !            26:        "ELGAMAL_ENC_ONLY",
        !            27:        "DSA",
        !            28:        "ECC",
        !            29:        "ECDSA",
        !            30:        "ELGAMAL",
        !            31:        "DIFFIE_HELLMAN"
        !            32: );
        !            33: ENUM_END(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_DIFFIE_HELLMAN);
        !            34: 
        !            35: ENUM(pgp_sym_alg_names, PGP_SYM_ALG_PLAIN, PGP_SYM_ALG_TWOFISH,
        !            36:        "PLAINTEXT",
        !            37:        "IDEA",
        !            38:        "3DES",
        !            39:        "CAST5",
        !            40:        "BLOWFISH",
        !            41:        "SAFER",
        !            42:        "DES",
        !            43:        "AES_128",
        !            44:        "AES_192",
        !            45:        "AES_256",
        !            46:        "TWOFISH"
        !            47: );
        !            48: 
        !            49: ENUM_BEGIN(pgp_packet_tag_names, PGP_PKT_RESERVED, PGP_PKT_PUBLIC_SUBKEY,
        !            50:        "Reserved",
        !            51:        "Public-Key Encrypted Session Key Packet",
        !            52:        "Signature Packet",
        !            53:        "Symmetric-Key Encrypted Session Key Packet",
        !            54:        "One-Pass Signature Packet",
        !            55:        "Secret Key Packet",
        !            56:        "Public Key Packet",
        !            57:        "Secret Subkey Packet",
        !            58:        "Compressed Data Packet",
        !            59:        "Symmetrically Encrypted Data Packet",
        !            60:        "Marker Packet",
        !            61:        "Literal Data Packet",
        !            62:        "Trust Packet",
        !            63:        "User ID Packet",
        !            64:        "Public Subkey Packet"
        !            65: );
        !            66: ENUM_NEXT(pgp_packet_tag_names, PGP_PKT_USER_ATTRIBUTE, PGP_PKT_MOD_DETECT_CODE, PGP_PKT_PUBLIC_SUBKEY,
        !            67:        "User Attribute Packet",
        !            68:        "Sym. Encrypted and Integrity Protected Data Packet",
        !            69:        "Modification Detection Code Packet"
        !            70: );
        !            71: ENUM_END(pgp_packet_tag_names, PGP_PKT_MOD_DETECT_CODE);
        !            72: 
        !            73: /**
        !            74:  * Read a PGP scalar of bytes length, advance blob
        !            75:  */
        !            76: bool pgp_read_scalar(chunk_t *blob, size_t bytes, uint32_t *scalar)
        !            77: {
        !            78:        uint32_t res = 0;
        !            79: 
        !            80:        if (bytes > blob->len)
        !            81:        {
        !            82:                DBG1(DBG_ASN, "PGP data too short to read %d byte scalar", bytes);
        !            83:                return FALSE;
        !            84:        }
        !            85:        while (bytes-- > 0)
        !            86:        {
        !            87:                res = 256 * res + blob->ptr[0];
        !            88:                *blob = chunk_skip(*blob, 1);
        !            89:        }
        !            90:        *scalar = res;
        !            91:        return TRUE;
        !            92: }
        !            93: 
        !            94: /**
        !            95:  * Read a PGP MPI, advance blob
        !            96:  */
        !            97: bool pgp_read_mpi(chunk_t *blob, chunk_t *mpi)
        !            98: {
        !            99:        uint32_t bits, bytes;
        !           100: 
        !           101:        if (!pgp_read_scalar(blob, 2, &bits))
        !           102:        {
        !           103:                DBG1(DBG_ASN, "PGP data too short to read MPI length");
        !           104:                return FALSE;
        !           105:        }
        !           106:        bytes = (bits + 7) / 8;
        !           107:        if (bytes > blob->len)
        !           108:        {
        !           109:                DBG1(DBG_ASN, "PGP data too short to read %d byte MPI", bytes);
        !           110:                return FALSE;
        !           111:        }
        !           112:        *mpi = chunk_create(blob->ptr, bytes);
        !           113:        *blob = chunk_skip(*blob, bytes);
        !           114:        return TRUE;
        !           115: }
        !           116: 
        !           117: /**
        !           118:  * Read length of an PGP old packet length encoding
        !           119:  */
        !           120: static bool pgp_old_packet_length(chunk_t *blob, uint32_t *length)
        !           121: {
        !           122:        /* bits 0 and 1 define the packet length type */
        !           123:        u_char type;
        !           124: 
        !           125:        if (!blob->len)
        !           126:        {
        !           127:                return FALSE;
        !           128:        }
        !           129:        type = 0x03 & blob->ptr[0];
        !           130:        *blob = chunk_skip(*blob, 1);
        !           131: 
        !           132:        if (type > 2)
        !           133:        {
        !           134:                return FALSE;
        !           135:        }
        !           136:        return pgp_read_scalar(blob, type == 0 ? 1 : type * 2, length);
        !           137: }
        !           138: 
        !           139: /**
        !           140:  * See header.
        !           141:  */
        !           142: bool pgp_read_packet(chunk_t *blob, chunk_t *data, pgp_packet_tag_t *tag)
        !           143: {
        !           144:        uint32_t len;
        !           145:        u_char t;
        !           146: 
        !           147:        if (!blob->len)
        !           148:        {
        !           149:                DBG1(DBG_ASN, "missing input");
        !           150:                return FALSE;
        !           151:        }
        !           152:        t = blob->ptr[0];
        !           153: 
        !           154:        /* bit 7 must be set */
        !           155:        if (!(t & 0x80))
        !           156:        {
        !           157:                DBG1(DBG_ASN, "invalid packet tag");
        !           158:                return FALSE;
        !           159:        }
        !           160:        /* bit 6 set defines new packet format */
        !           161:        if (t & 0x40)
        !           162:        {
        !           163:                DBG1(DBG_ASN, "new PGP packet format not supported");
        !           164:                return FALSE;
        !           165:        }
        !           166: 
        !           167:        t = (t & 0x3C) >> 2;
        !           168:        if (!pgp_old_packet_length(blob, &len) || len > blob->len)
        !           169:        {
        !           170:                DBG1(DBG_ASN, "invalid packet length");
        !           171:                return FALSE;
        !           172:        }
        !           173:        *data = chunk_create(blob->ptr, len);
        !           174:        *blob = chunk_skip(*blob, len);
        !           175:        *tag = t;
        !           176:        DBG2(DBG_ASN, "L1 - PGP %N (%u bytes)", pgp_packet_tag_names, t, len);
        !           177:        DBG3(DBG_ASN, "%B", data);
        !           178:        return TRUE;
        !           179: }
        !           180: 

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