Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pgp/pgp_builder.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2009 Martin Willi
! 3: * Copyright (C) 2002-2009 Andreas Steffen
! 4: * HSR Hochschule fuer Technik Rapperswil
! 5: *
! 6: * This program is free software; you can redistribute it and/or modify it
! 7: * under the terms of the GNU General Public License as published by the
! 8: * Free Software Foundation; either version 2 of the License, or (at your
! 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 10: *
! 11: * This program is distributed in the hope that it will be useful, but
! 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 14: * for more details.
! 15: */
! 16:
! 17: #include "pgp_builder.h"
! 18: #include "pgp_utils.h"
! 19:
! 20: #include <utils/utils.h>
! 21: #include <utils/debug.h>
! 22: #include <credentials/keys/private_key.h>
! 23:
! 24: /**
! 25: * Load a generic public key from a PGP packet
! 26: */
! 27: static public_key_t *parse_public_key(chunk_t blob)
! 28: {
! 29: uint32_t alg;
! 30: public_key_t *key;
! 31:
! 32: if (!pgp_read_scalar(&blob, 1, &alg))
! 33: {
! 34: return NULL;
! 35: }
! 36: switch (alg)
! 37: {
! 38: case PGP_PUBKEY_ALG_RSA:
! 39: case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
! 40: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
! 41: BUILD_BLOB_PGP, blob, BUILD_END);
! 42: break;
! 43: default:
! 44: DBG1(DBG_LIB, "PGP public key algorithm %N not supported",
! 45: pgp_pubkey_alg_names, alg);
! 46: return NULL;
! 47: }
! 48: return key;
! 49: }
! 50:
! 51: /**
! 52: * Load a RSA public key from a PGP packet
! 53: */
! 54: static public_key_t *parse_rsa_public_key(chunk_t blob)
! 55: {
! 56: chunk_t mpi[2];
! 57: int i;
! 58:
! 59: for (i = 0; i < 2; i++)
! 60: {
! 61: if (!pgp_read_mpi(&blob, &mpi[i]))
! 62: {
! 63: return NULL;
! 64: }
! 65: }
! 66: return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
! 67: BUILD_RSA_MODULUS, mpi[0], BUILD_RSA_PUB_EXP, mpi[1],
! 68: BUILD_END);
! 69: }
! 70:
! 71: /**
! 72: * Load a RSA private key from a PGP packet
! 73: */
! 74: static private_key_t *parse_rsa_private_key(chunk_t blob)
! 75: {
! 76: chunk_t mpi[6];
! 77: uint32_t s2k;
! 78: int i;
! 79:
! 80: for (i = 0; i < 2; i++)
! 81: {
! 82: if (!pgp_read_mpi(&blob, &mpi[i]))
! 83: {
! 84: return NULL;
! 85: }
! 86: }
! 87: if (!pgp_read_scalar(&blob, 1, &s2k))
! 88: {
! 89: return NULL;
! 90: }
! 91: if (s2k == 255 || s2k == 254)
! 92: {
! 93: DBG1(DBG_LIB, "string-to-key specifiers not supported");
! 94: return NULL;
! 95: }
! 96: if (s2k != PGP_SYM_ALG_PLAIN)
! 97: {
! 98: DBG1(DBG_LIB, "%N private key encryption not supported",
! 99: pgp_sym_alg_names, s2k);
! 100: return NULL;
! 101: }
! 102:
! 103: for (i = 2; i < 6; i++)
! 104: {
! 105: if (!pgp_read_mpi(&blob, &mpi[i]))
! 106: {
! 107: return NULL;
! 108: }
! 109: }
! 110:
! 111: /* PGP has uses p < q, but we use p > q */
! 112: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
! 113: BUILD_RSA_MODULUS, mpi[0], BUILD_RSA_PUB_EXP, mpi[1],
! 114: BUILD_RSA_PRIV_EXP, mpi[2], BUILD_RSA_PRIME2, mpi[3],
! 115: BUILD_RSA_PRIME1, mpi[4], BUILD_RSA_COEFF, mpi[5],
! 116: BUILD_END);
! 117: }
! 118:
! 119: METHOD(private_key_t, sign_not_allowed, bool,
! 120: private_key_t *this, signature_scheme_t scheme, void *params,
! 121: chunk_t data, chunk_t *signature)
! 122: {
! 123: DBG1(DBG_LIB, "signing failed - decryption only key");
! 124: return FALSE;
! 125: }
! 126:
! 127: METHOD(private_key_t, decrypt_not_allowed, bool,
! 128: private_key_t *this, encryption_scheme_t scheme,
! 129: chunk_t crypto, chunk_t *plain)
! 130: {
! 131: DBG1(DBG_LIB, "decryption failed - signature only key");
! 132: return FALSE;
! 133: }
! 134:
! 135: /**
! 136: * Load a generic private key from a PGP packet
! 137: */
! 138: static private_key_t *parse_private_key(chunk_t blob)
! 139: {
! 140: chunk_t packet;
! 141: pgp_packet_tag_t tag;
! 142: uint32_t version, created, days, alg;
! 143: private_key_t *key;
! 144:
! 145: if (!pgp_read_packet(&blob, &packet, &tag))
! 146: {
! 147: return NULL;
! 148: }
! 149: if (!pgp_read_scalar(&packet, 1, &version))
! 150: {
! 151: return NULL;
! 152: }
! 153: switch (version)
! 154: {
! 155: case 3:
! 156: if (!pgp_read_scalar(&packet, 2, &days))
! 157: {
! 158: return NULL;
! 159: }
! 160: break;
! 161: case 4:
! 162: break;
! 163: default:
! 164: DBG1(DBG_LIB, "PGP packet version V%d not supported", version);
! 165: return NULL;
! 166: }
! 167: if (!pgp_read_scalar(&packet, 4, &created))
! 168: {
! 169: return NULL;
! 170: }
! 171: if (!pgp_read_scalar(&packet, 1, &alg))
! 172: {
! 173: return NULL;
! 174: }
! 175: switch (alg)
! 176: {
! 177: case PGP_PUBKEY_ALG_RSA:
! 178: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
! 179: BUILD_BLOB_PGP, packet, BUILD_END);
! 180: case PGP_PUBKEY_ALG_RSA_ENC_ONLY:
! 181: key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
! 182: BUILD_BLOB_PGP, packet, BUILD_END);
! 183: if (key)
! 184: {
! 185: key->sign = _sign_not_allowed;
! 186: }
! 187: return key;
! 188: case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
! 189: key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
! 190: BUILD_BLOB_PGP, packet, BUILD_END);
! 191: if (key)
! 192: {
! 193: key->decrypt = _decrypt_not_allowed;
! 194: }
! 195: return key;
! 196: case PGP_PUBKEY_ALG_ECDSA:
! 197: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
! 198: BUILD_BLOB_PGP, packet, BUILD_END);
! 199: case PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY:
! 200: case PGP_PUBKEY_ALG_DSA:
! 201: case PGP_PUBKEY_ALG_ECC:
! 202: case PGP_PUBKEY_ALG_ELGAMAL:
! 203: case PGP_PUBKEY_ALG_DIFFIE_HELLMAN:
! 204: default:
! 205: return NULL;
! 206: }
! 207: }
! 208:
! 209: /**
! 210: * See header.
! 211: */
! 212: public_key_t *pgp_public_key_load(key_type_t type, va_list args)
! 213: {
! 214: chunk_t blob = chunk_empty;
! 215:
! 216: while (TRUE)
! 217: {
! 218: switch (va_arg(args, builder_part_t))
! 219: {
! 220: case BUILD_BLOB_PGP:
! 221: blob = va_arg(args, chunk_t);
! 222: continue;
! 223: case BUILD_END:
! 224: break;
! 225: default:
! 226: return NULL;
! 227: }
! 228: break;
! 229: }
! 230: switch (type)
! 231: {
! 232: case KEY_ANY:
! 233: return parse_public_key(blob);
! 234: case KEY_RSA:
! 235: return parse_rsa_public_key(blob);
! 236: default:
! 237: return NULL;
! 238: }
! 239: }
! 240:
! 241: /**
! 242: * See header.
! 243: */
! 244: private_key_t *pgp_private_key_load(key_type_t type, va_list args)
! 245: {
! 246: chunk_t blob = chunk_empty;
! 247:
! 248: while (TRUE)
! 249: {
! 250: switch (va_arg(args, builder_part_t))
! 251: {
! 252: case BUILD_BLOB_PGP:
! 253: blob = va_arg(args, chunk_t);
! 254: continue;
! 255: case BUILD_END:
! 256: break;
! 257: default:
! 258: return NULL;
! 259: }
! 260: break;
! 261: }
! 262: switch (type)
! 263: {
! 264: case KEY_ANY:
! 265: return parse_private_key(blob);
! 266: case KEY_RSA:
! 267: return parse_rsa_private_key(blob);
! 268: default:
! 269: return NULL;
! 270: }
! 271: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>