Return to pkcs1_builder.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / pkcs1 |
1.1 misho 1: /* 2: * Copyright (C) 2008-2016 Tobias Brunner 3: * Copyright (C) 2008-2009 Martin Willi 4: * Copyright (C) 2000-2008 Andreas Steffen 5: * HSR Hochschule fuer Technik Rapperswil 6: * 7: * This program is free software; you can redistribute it and/or modify it 8: * under the terms of the GNU General Public License as published by the 9: * Free Software Foundation; either version 2 of the License, or (at your 10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 11: * 12: * This program is distributed in the hope that it will be useful, but 13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15: * for more details. 16: */ 17: 18: #include "pkcs1_builder.h" 19: 20: #include <utils/debug.h> 21: #include <asn1/oid.h> 22: #include <asn1/asn1.h> 23: #include <asn1/asn1_parser.h> 24: #include <credentials/keys/private_key.h> 25: 26: /** 27: * ASN.1 definition of a subjectPublicKeyInfo structure 28: */ 29: static const asn1Object_t pkinfoObjects[] = { 30: { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ 31: { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */ 32: { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */ 33: { 0, "exit", ASN1_EOC, ASN1_EXIT } 34: }; 35: #define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM 1 36: #define PKINFO_SUBJECT_PUBLIC_KEY 2 37: 38: /** 39: * Load a generic public key from an ASN.1 encoded blob 40: */ 41: static public_key_t *parse_public_key(chunk_t blob) 42: { 43: asn1_parser_t *parser; 44: chunk_t object; 45: int objectID; 46: public_key_t *key = NULL; 47: key_type_t type = KEY_ANY; 48: 49: parser = asn1_parser_create(pkinfoObjects, blob); 50: 51: while (parser->iterate(parser, &objectID, &object)) 52: { 53: switch (objectID) 54: { 55: case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM: 56: { 57: int oid = asn1_parse_algorithmIdentifier(object, 58: parser->get_level(parser)+1, NULL); 59: 60: if (oid == OID_RSA_ENCRYPTION || oid == OID_RSAES_OAEP || 61: oid == OID_RSASSA_PSS) 62: { 63: /* TODO: we should parse parameters for PSS and pass them 64: * (and the type), or the complete subjectPublicKeyInfo, 65: * along so we can treat these as restrictions when 66: * generating signatures with the associated private key */ 67: type = KEY_RSA; 68: } 69: else if (oid == OID_EC_PUBLICKEY) 70: { 71: /* Need the whole subjectPublicKeyInfo for EC public keys */ 72: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, 73: KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END); 74: goto end; 75: } 76: else if (oid == OID_BLISS_PUBLICKEY) 77: { 78: /* Need the whole subjectPublicKeyInfo for BLISS public keys */ 79: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, 80: KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END); 81: goto end; 82: } 83: else if (oid == OID_ED25519) 84: { 85: /* Need the whole subjectPublicKeyInfo for Ed25519 public keys */ 86: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, 87: KEY_ED25519, BUILD_BLOB_ASN1_DER, blob, BUILD_END); 88: goto end; 89: } 90: else if (oid == OID_ED448) 91: { 92: /* Need the whole subjectPublicKeyInfo for Ed448 public keys */ 93: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, 94: KEY_ED448, BUILD_BLOB_ASN1_DER, blob, BUILD_END); 95: goto end; 96: } 97: else 98: { 99: /* key type not supported */ 100: goto end; 101: } 102: break; 103: } 104: case PKINFO_SUBJECT_PUBLIC_KEY: 105: if (object.len > 0 && *object.ptr == 0x00) 106: { 107: /* skip initial bit string octet defining 0 unused bits */ 108: object = chunk_skip(object, 1); 109: } 110: DBG2(DBG_ASN, "-- > --"); 111: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type, 112: BUILD_BLOB_ASN1_DER, object, BUILD_END); 113: DBG2(DBG_ASN, "-- < --"); 114: break; 115: } 116: } 117: 118: end: 119: parser->destroy(parser); 120: return key; 121: } 122: 123: /** 124: * ASN.1 definition of RSApublicKey 125: */ 126: static const asn1Object_t pubkeyObjects[] = { 127: { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */ 128: { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */ 129: { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */ 130: { 0, "exit", ASN1_EOC, ASN1_EXIT } 131: }; 132: #define PUB_KEY_RSA_PUBLIC_KEY 0 133: #define PUB_KEY_MODULUS 1 134: #define PUB_KEY_EXPONENT 2 135: 136: /** 137: * Load a RSA public key from an ASN.1 encoded blob. 138: */ 139: static public_key_t *parse_rsa_public_key(chunk_t blob) 140: { 141: chunk_t n, e; 142: asn1_parser_t *parser; 143: chunk_t object; 144: int objectID; 145: bool success = FALSE; 146: 147: parser = asn1_parser_create(pubkeyObjects, blob); 148: 149: while (parser->iterate(parser, &objectID, &object)) 150: { 151: switch (objectID) 152: { 153: case PUB_KEY_MODULUS: 154: n = object; 155: break; 156: case PUB_KEY_EXPONENT: 157: e = object; 158: break; 159: } 160: } 161: success = parser->success(parser); 162: parser->destroy(parser); 163: 164: if (!success) 165: { 166: return NULL; 167: } 168: return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, 169: BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END); 170: } 171: 172: /** 173: * ASN.1 definition of a PKCS#1 RSA private key 174: */ 175: static const asn1Object_t privkeyObjects[] = { 176: { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ 177: { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */ 178: { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */ 179: { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */ 180: { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */ 181: { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */ 182: { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */ 183: { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */ 184: { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */ 185: { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */ 186: { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT | 187: ASN1_LOOP }, /* 10 */ 188: { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */ 189: { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */ 190: { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */ 191: { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */ 192: { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */ 193: { 0, "exit", ASN1_EOC, ASN1_EXIT } 194: }; 195: #define PRIV_KEY_VERSION 1 196: #define PRIV_KEY_MODULUS 2 197: #define PRIV_KEY_PUB_EXP 3 198: #define PRIV_KEY_PRIV_EXP 4 199: #define PRIV_KEY_PRIME1 5 200: #define PRIV_KEY_PRIME2 6 201: #define PRIV_KEY_EXP1 7 202: #define PRIV_KEY_EXP2 8 203: #define PRIV_KEY_COEFF 9 204: 205: /** 206: * Load a RSA private key from a ASN1 encoded blob. 207: */ 208: static private_key_t *parse_rsa_private_key(chunk_t blob) 209: { 210: chunk_t n, e, d, p, q, exp1, exp2, coeff; 211: asn1_parser_t *parser; 212: chunk_t object; 213: int objectID ; 214: bool success = FALSE; 215: 216: parser = asn1_parser_create(privkeyObjects, blob); 217: parser->set_flags(parser, FALSE, TRUE); 218: 219: while (parser->iterate(parser, &objectID, &object)) 220: { 221: switch (objectID) 222: { 223: case PRIV_KEY_VERSION: 224: if (object.len > 0 && *object.ptr != 0) 225: { 226: goto end; 227: } 228: break; 229: case PRIV_KEY_MODULUS: 230: n = object; 231: break; 232: case PRIV_KEY_PUB_EXP: 233: e = object; 234: break; 235: case PRIV_KEY_PRIV_EXP: 236: d = object; 237: break; 238: case PRIV_KEY_PRIME1: 239: p = object; 240: break; 241: case PRIV_KEY_PRIME2: 242: q = object; 243: break; 244: case PRIV_KEY_EXP1: 245: exp1 = object; 246: break; 247: case PRIV_KEY_EXP2: 248: exp2 = object; 249: break; 250: case PRIV_KEY_COEFF: 251: coeff = object; 252: break; 253: } 254: } 255: success = parser->success(parser); 256: 257: end: 258: parser->destroy(parser); 259: if (!success) 260: { 261: return NULL; 262: } 263: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, 264: BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_RSA_PRIV_EXP, d, 265: BUILD_RSA_PRIME1, p, BUILD_RSA_PRIME2, q, BUILD_RSA_EXP1, exp1, 266: BUILD_RSA_EXP2, exp2, BUILD_RSA_COEFF, coeff, BUILD_END); 267: } 268: 269: /** 270: * Check if the ASN.1 structure looks like an EC private key according to 271: * RFC 5915. 272: * 273: * ECPrivateKey :=: SEQUENCE { 274: * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 275: * privateKey OCTET STRING, 276: * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 277: * publicKey [1] BIT STRING OPTIONAL 278: * } 279: * 280: * While the parameters and publicKey fields are OPTIONAL, RFC 5915 says that 281: * parameters MUST be included (an errata clarifies this, so this is only the 282: * case for plain private keys, not encoded in PKCS#8) and publicKey SHOULD be. 283: */ 284: static bool is_ec_private_key(chunk_t blob) 285: { 286: chunk_t data; 287: return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE && 288: asn1_unwrap(&blob, &data) == ASN1_INTEGER && 289: asn1_parse_integer_uint64(data) == 1 && 290: asn1_unwrap(&blob, &data) == ASN1_OCTET_STRING && 291: asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_0 && 292: asn1_unwrap(&data, &data) == ASN1_OID && 293: (!blob.len || (asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_1)); 294: } 295: 296: /** 297: * Check if the ASN.1 structure looks like a BLISS private key. 298: */ 299: static bool is_bliss_private_key(chunk_t blob) 300: { 301: chunk_t data; 302: return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE && 303: asn1_unwrap(&blob, &data) == ASN1_OID && 304: asn1_unwrap(&blob, &data) == ASN1_BIT_STRING && 305: asn1_unwrap(&blob, &data) == ASN1_BIT_STRING && 306: asn1_unwrap(&blob, &data) == ASN1_BIT_STRING; 307: } 308: 309: /** 310: * Load a private key from an ASN.1 encoded blob trying to detect the type 311: * automatically. 312: */ 313: static private_key_t *parse_private_key(chunk_t blob) 314: { 315: if (is_ec_private_key(blob)) 316: { 317: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, 318: BUILD_BLOB_ASN1_DER, blob, BUILD_END); 319: } 320: else if (is_bliss_private_key(blob)) 321: { 322: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, 323: BUILD_BLOB_ASN1_DER, blob, BUILD_END); 324: } 325: return parse_rsa_private_key(blob); 326: } 327: 328: /** 329: * See header. 330: */ 331: public_key_t *pkcs1_public_key_load(key_type_t type, va_list args) 332: { 333: chunk_t blob = chunk_empty; 334: 335: while (TRUE) 336: { 337: switch (va_arg(args, builder_part_t)) 338: { 339: case BUILD_BLOB_ASN1_DER: 340: blob = va_arg(args, chunk_t); 341: continue; 342: case BUILD_END: 343: break; 344: default: 345: return NULL; 346: } 347: break; 348: } 349: switch (type) 350: { 351: case KEY_ANY: 352: return parse_public_key(blob); 353: case KEY_RSA: 354: return parse_rsa_public_key(blob); 355: default: 356: return NULL; 357: } 358: } 359: 360: /** 361: * See header. 362: */ 363: private_key_t *pkcs1_private_key_load(key_type_t type, va_list args) 364: { 365: chunk_t blob = chunk_empty; 366: 367: while (TRUE) 368: { 369: switch (va_arg(args, builder_part_t)) 370: { 371: case BUILD_BLOB_ASN1_DER: 372: blob = va_arg(args, chunk_t); 373: continue; 374: case BUILD_END: 375: break; 376: default: 377: return NULL; 378: } 379: break; 380: } 381: switch (type) 382: { 383: case KEY_ANY: 384: return parse_private_key(blob); 385: case KEY_RSA: 386: return parse_rsa_private_key(blob); 387: default: 388: return NULL; 389: } 390: } 391: