📄 pgp.c
字号:
/* Support of OpenPGP certificates * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * RCSID $Id: pgp.c,v 1.8 2004/09/08 17:16:52 ken Exp $ */#include <stdlib.h>#include <string.h>#include <time.h>#include <openswan.h>#include <openswan/ipsec_policy.h>#include "constants.h"#include "oswlog.h"#include "defs.h"#include "log.h"#include "id.h"#include "pgp.h"#include "x509.h"#include "certs.h"#include "md5.h"#include "whack.h"#include "keys.h"/* * Size of temporary buffers */#define BUF_LEN 256/* * chained list of OpenPGP end certificates */static pgpcert_t *pgpcerts = NULL;/* * OpenPGP packet tags defined in section 4.3 of RFC 2440 */#define PGP_PKT_RESERVED 0#define PGP_PKT_PUBKEY_ENC_SESSION_KEY 1#define PGP_PKT_SIGNATURE 2#define PGP_PKT_SYMKEY_ENC_SESSION_KEY 3#define PGP_PKT_ONE_PASS_SIGNATURE_PKT 4#define PGP_PKT_SECRET_KEY 5#define PGP_PKT_PUBLIC_KEY 6#define PGP_PKT_SECRET_SUBKEY 7#define PGP_PKT_COMPRESSED_DATA 8#define PGP_PKT_SYMKEY_ENC_DATA 9#define PGP_PKT_MARKER 10#define PGP_PKT_LITERAL_DATA 11#define PGP_PKT_TRUST 12#define PGP_PKT_USER_ID 13#define PGP_PKT_PUBLIC_SUBKEY 14#define PGP_PKT_ROOF 15static const char *const pgp_packet_type_name[] = { "Reserved", "Public-Key Encrypted Session Key Packet", "Signature Packet", "Symmetric-Key Encrypted Session Key Packet", "One-Pass Signature Packet", "Secret Key Packet", "Public Key Packet", "Secret Subkey Packet", "Compressed Data Packet", "Symmetrically Encrypted Data Packet", "Marker Packet", "Literal Data Packet", "Trust Packet", "User ID Packet", "Public Subkey Packet"};/* * OpenPGP public key algorithms defined in section 9.1 of RFC 2440 */#define PGP_PUBKEY_ALG_RSA 1#define PGP_PUBKEY_ALG_RSA_ENC_ONLY 2#define PGP_PUBKEY_ALG_RSA_SIGN_ONLY 3#define PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY 16#define PGP_PUBKEY_ALG_DSA 17#define PGP_PUBKEY_ALG_ECC 18#define PGP_PUBKEY_ALG_ECDSA 19#define PGP_PUBKEY_ALG_ELGAMAL 20/* * OpenPGP symmetric key algorithms defined in section 9.2 of RFC 2440 */#define PGP_SYM_ALG_PLAIN 0#define PGP_SYM_ALG_IDEA 1#define PGP_SYM_ALG_3DES 2#define PGP_SYM_ALG_CAST5 3#define PGP_SYM_ALG_BLOWFISH 4#define PGP_SYM_ALG_SAFER 5#define PGP_SYM_ALG_DES 6#define PGP_SYM_ALG_AES 7#define PGP_SYM_ALG_AES_192 8#define PGP_SYM_ALG_AES_256 9#define PGP_SYM_ALG_TWOFISH 10#define PGP_SYM_ALG_ROOF 11static const char *const pgp_sym_alg_name[] = { "Plaintext", "IDEA", "3DES", "CAST5", "Blowfish", "SAFER", "DES", "AES", "AES-192", "AES-256", "Twofish"};/* * Size of PGP Key ID */#define PGP_KEYID_SIZE 8const pgpcert_t empty_pgpcert = { NULL , /* *next */ 0 , /* installed */ 0 , /* count */ { NULL, 0 }, /* certificate */ 0 , /* created */ 0 , /* until */ 0 , /* pubkeyAlgorithm */ { NULL, 0 }, /* modulus */ { NULL, 0 }, /* publicExponent */ "" /* fingerprint */};static const char *const pgp_rsa_privkey_name[] = { "private exponent", "prime1", "prime2"};static size_tpgp_size(chunk_t *blob, int len){ size_t size = 0; blob->len -= len; while (len-- > 0) size = 256*size + *blob->ptr++; return size;}/* * extracts the length of a PGP packet */static size_tpgp_old_packet_length(chunk_t *blob){ /* bits 0 and 1 define the packet length type */ int len_type = 0x03 & *blob->ptr++; blob->len--; /* len_type: 0 -> 1 byte, 1 -> 2 bytes, 2 -> 4 bytes */ return pgp_size(blob, (len_type == 0)? 1: len_type << 1);}/* * extracts PGP packet version (V3 or V4) */static u_charpgp_version(chunk_t *blob){ u_char version = *blob->ptr++; blob->len--; DBG(DBG_PARSING, DBG_log("L3 - version:"); DBG_log(" V%d", version) ) return version;}/* * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 2440 */static boolparse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert){ u_char version = pgp_version(packet); if (version < 3 || version > 4) { openswan_log("PGP packet version V%d not supported", version); return FALSE; } /* creation date - 4 bytes */ cert->created = (time_t)pgp_size(packet, 4); DBG(DBG_PARSING, char tbuf[TIMETOA_BUF]; DBG_log("L3 - created:"); DBG_log(" %s", timetoa(&cert->created, TRUE, tbuf, sizeof(tbuf))) ) if (version == 3) { /* validity in days - 2 bytes */ cert->until = (time_t)pgp_size(packet, 2); /* validity of 0 days means that the key never expires */ if (cert->until > 0) cert->until = cert->created + 24*3600*cert->until; DBG(DBG_PARSING, char tbuf[TIMETOA_BUF]; DBG_log("L3 - until:"); DBG_log(" %s", timetoa(&cert->until, TRUE, tbuf, sizeof(tbuf))) ) } /* public key algorithm - 1 byte */ DBG(DBG_PARSING, DBG_log("L3 - public key algorithm:") ) switch (pgp_size(packet, 1)) { case PGP_PUBKEY_ALG_RSA: case PGP_PUBKEY_ALG_RSA_SIGN_ONLY: cert->pubkeyAlg = PUBKEY_ALG_RSA; DBG(DBG_PARSING, DBG_log(" RSA") ) /* modulus n */ cert->modulus.len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE; cert->modulus.ptr = packet->ptr; packet->ptr += cert->modulus.len; packet->len -= cert->modulus.len; DBG(DBG_PARSING, DBG_log("L3 - modulus:") ) DBG_cond_dump_chunk(DBG_RAW, "", cert->modulus); /* public exponent e */ cert->publicExponent.len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE; cert->publicExponent.ptr = packet->ptr; packet->ptr += cert->publicExponent.len; packet->len -= cert->publicExponent.len; DBG(DBG_PARSING, DBG_log("L3 - public exponent:") ) DBG_cond_dump_chunk(DBG_RAW, "", cert->publicExponent); if (version == 3) { /* a V3 fingerprint is the MD5 hash of modulus and public exponent */ MD5_CTX context; osMD5Init(&context); osMD5Update(&context, cert->modulus.ptr, cert->modulus.len); osMD5Update(&context, cert->publicExponent.ptr, cert->publicExponent.len); osMD5Final(cert->fingerprint, &context); } else { openswan_log(" computation of V4 key ID not implemented yet"); } break; case PGP_PUBKEY_ALG_DSA: cert->pubkeyAlg = PUBKEY_ALG_DSA; DBG(DBG_PARSING, DBG_log(" DSA") ) openswan_log(" DSA public keys not supported"); return FALSE; default: cert->pubkeyAlg = 0; DBG(DBG_PARSING, DBG_log(" other") ) openswan_log(" exotic not RSA public keys not supported"); return FALSE; } return TRUE;}/* * Parse OpenPGP secret key packet defined in section 5.5.3 of RFC 2440 */static boolparse_pgp_secretkey_packet(chunk_t *packet, rsa_privkey_t *key){ int i; int s2k; pgpcert_t cert = empty_pgpcert; if (!parse_pgp_pubkey_packet(packet, &cert)) return FALSE; /* copy public key into private key fields */ key->field[0] = cert.modulus; key->field[1] = cert.publicExponent; /* string-to-key usage */ s2k = pgp_size(packet, 1); DBG(DBG_PARSING, DBG_log("L3 - string-to-key: %d", s2k) ) if (s2k == 255) { openswan_log(" string-to-key specifiers not supported"); return FALSE; } if (s2k >= PGP_SYM_ALG_ROOF) { openswan_log(" undefined symmetric key algorithm"); return FALSE; } /* a known symmetric key algorithm is specified*/ DBG(DBG_PARSING,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -