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