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>