Return to pgp_utils.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / pgp |
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: