Return to pgp_builder.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: * 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: }