Annotation of embedaddon/strongswan/src/pki/commands/req.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2009 Martin Willi
! 3: * Copyright (C) 2009-2017 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 <time.h>
! 18: #include <errno.h>
! 19:
! 20: #include "pki.h"
! 21:
! 22: #include <collections/linked_list.h>
! 23: #include <credentials/certificates/certificate.h>
! 24:
! 25: /**
! 26: * Create a self-signed PKCS#10 certificate request.
! 27: */
! 28: static int req()
! 29: {
! 30: cred_encoding_type_t form = CERT_ASN1_DER;
! 31: key_type_t type = KEY_ANY;
! 32: hash_algorithm_t digest = HASH_UNKNOWN;
! 33: signature_params_t *scheme = NULL;
! 34: certificate_t *cert = NULL;
! 35: private_key_t *private = NULL;
! 36: char *file = NULL, *keyid = NULL, *dn = NULL, *error = NULL;
! 37: identification_t *id = NULL;
! 38: linked_list_t *san;
! 39: chunk_t encoding = chunk_empty;
! 40: chunk_t challenge_password = chunk_empty;
! 41: char *arg;
! 42: bool pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
! 43: lib->ns);
! 44:
! 45: san = linked_list_create();
! 46:
! 47: while (TRUE)
! 48: {
! 49: switch (command_getopt(&arg))
! 50: {
! 51: case 'h':
! 52: goto usage;
! 53: case 't':
! 54: if (streq(arg, "rsa"))
! 55: {
! 56: type = KEY_RSA;
! 57: }
! 58: else if (streq(arg, "ecdsa"))
! 59: {
! 60: type = KEY_ECDSA;
! 61: }
! 62: else if (streq(arg, "bliss"))
! 63: {
! 64: type = KEY_BLISS;
! 65: }
! 66: else if (streq(arg, "priv"))
! 67: {
! 68: type = KEY_ANY;
! 69: }
! 70: else
! 71: {
! 72: error = "invalid input type";
! 73: goto usage;
! 74: }
! 75: continue;
! 76: case 'g':
! 77: if (!enum_from_name(hash_algorithm_short_names, arg, &digest))
! 78: {
! 79: error = "invalid --digest type";
! 80: goto usage;
! 81: }
! 82: continue;
! 83: case 'R':
! 84: if (streq(arg, "pss"))
! 85: {
! 86: pss = TRUE;
! 87: }
! 88: else if (!streq(arg, "pkcs1"))
! 89: {
! 90: error = "invalid RSA padding";
! 91: goto usage;
! 92: }
! 93: continue;
! 94: case 'i':
! 95: file = arg;
! 96: continue;
! 97: case 'd':
! 98: dn = arg;
! 99: continue;
! 100: case 'a':
! 101: san->insert_last(san, identification_create_from_string(arg));
! 102: continue;
! 103: case 'p':
! 104: challenge_password = chunk_create(arg, strlen(arg));
! 105: continue;
! 106: case 'f':
! 107: if (!get_form(arg, &form, CRED_CERTIFICATE))
! 108: {
! 109: error = "invalid output format";
! 110: goto usage;
! 111: }
! 112: continue;
! 113: case 'x':
! 114: keyid = arg;
! 115: continue;
! 116: case EOF:
! 117: break;
! 118: default:
! 119: error = "invalid --req option";
! 120: goto usage;
! 121: }
! 122: break;
! 123: }
! 124:
! 125: if (!dn)
! 126: {
! 127: error = "--dn is required";
! 128: goto usage;
! 129: }
! 130: id = identification_create_from_string(dn);
! 131: if (id->get_type(id) != ID_DER_ASN1_DN)
! 132: {
! 133: error = "supplied --dn is not a distinguished name";
! 134: goto end;
! 135: }
! 136: if (file)
! 137: {
! 138: private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
! 139: BUILD_FROM_FILE, file, BUILD_END);
! 140: }
! 141: else if (keyid)
! 142: {
! 143: chunk_t chunk;
! 144:
! 145: chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
! 146: private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
! 147: BUILD_PKCS11_KEYID, chunk, BUILD_END);
! 148: free(chunk.ptr);
! 149: }
! 150: else
! 151: {
! 152: chunk_t chunk;
! 153:
! 154: set_file_mode(stdin, CERT_ASN1_DER);
! 155: if (!chunk_from_fd(0, &chunk))
! 156: {
! 157: fprintf(stderr, "reading private key failed: %s\n", strerror(errno));
! 158: error = "";
! 159: goto end;
! 160: }
! 161: private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
! 162: BUILD_BLOB, chunk, BUILD_END);
! 163: free(chunk.ptr);
! 164: }
! 165: if (!private)
! 166: {
! 167: error = "parsing private key failed";
! 168: goto end;
! 169: }
! 170: scheme = get_signature_scheme(private, digest, pss);
! 171: if (!scheme)
! 172: {
! 173: error = "no signature scheme found";
! 174: goto end;
! 175: }
! 176:
! 177: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
! 178: BUILD_SIGNING_KEY, private,
! 179: BUILD_SUBJECT, id,
! 180: BUILD_SUBJECT_ALTNAMES, san,
! 181: BUILD_CHALLENGE_PWD, challenge_password,
! 182: BUILD_SIGNATURE_SCHEME, scheme,
! 183: BUILD_END);
! 184: if (!cert)
! 185: {
! 186: error = "generating certificate request failed";
! 187: goto end;
! 188: }
! 189: if (!cert->get_encoding(cert, form, &encoding))
! 190: {
! 191: error = "encoding certificate request failed";
! 192: goto end;
! 193: }
! 194: set_file_mode(stdout, form);
! 195: if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1)
! 196: {
! 197: error = "writing certificate request failed";
! 198: goto end;
! 199: }
! 200:
! 201: end:
! 202: DESTROY_IF(id);
! 203: DESTROY_IF(cert);
! 204: DESTROY_IF(private);
! 205: san->destroy_offset(san, offsetof(identification_t, destroy));
! 206: signature_params_destroy(scheme);
! 207: free(encoding.ptr);
! 208:
! 209: if (error)
! 210: {
! 211: fprintf(stderr, "%s\n", error);
! 212: return 1;
! 213: }
! 214: return 0;
! 215:
! 216: usage:
! 217: san->destroy_offset(san, offsetof(identification_t, destroy));
! 218: return command_usage(error);
! 219: }
! 220:
! 221: /**
! 222: * Register the command.
! 223: */
! 224: static void __attribute__ ((constructor))reg()
! 225: {
! 226: command_register((command_t) {
! 227: req, 'r', "req",
! 228: "create a PKCS#10 certificate request",
! 229: {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv] --dn distinguished-name",
! 230: "[--san subjectAltName]+ [--password challengePassword]",
! 231: "[--digest md5|sha1|sha224|sha256|sha384|sha512|sha3_224|sha3_256|sha3_384|sha3_512]",
! 232: "[--rsa-padding pkcs1|pss]",
! 233: "[--outform der|pem]"},
! 234: {
! 235: {"help", 'h', 0, "show usage information"},
! 236: {"in", 'i', 1, "private key input file, default: stdin"},
! 237: {"keyid", 'x', 1, "smartcard or TPM private key object handle"},
! 238: {"type", 't', 1, "type of input key, default: priv"},
! 239: {"dn", 'd', 1, "subject distinguished name"},
! 240: {"san", 'a', 1, "subjectAltName to include in cert request"},
! 241: {"password", 'p', 1, "challengePassword to include in cert request"},
! 242: {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
! 243: {"rsa-padding", 'R', 1, "padding for RSA signatures, default: pkcs1"},
! 244: {"outform", 'f', 1, "encoding of generated request, default: der"},
! 245: }
! 246: });
! 247: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>