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>