scepclient: Removal and replacement by pki subcommands
The "ipsec scepclient" tool has been removed and replaced by the pki subcommands "pki --scep" and "pki --scepca" which implement the new SCEP RFC 8894 standard that was released in September 2020 and which supports trusted "certificate renewal" based on the existing client certificate.
This commit is contained in:
+31
-36
@@ -302,7 +302,6 @@ ARG_ENABL_SET([medcli], [enable mediation client configuration database
|
||||
ARG_ENABL_SET([medsrv], [enable mediation server web frontend and daemon plugin.])
|
||||
ARG_ENABL_SET([nm], [enable NetworkManager backend.])
|
||||
ARG_DISBL_SET([pki], [disable pki certificate utility.])
|
||||
ARG_DISBL_SET([scepclient], [disable SCEP client tool.])
|
||||
ARG_DISBL_SET([scripts], [disable additional utilities (found in directory scripts).])
|
||||
ARG_ENABL_SET([svc], [enable charon Windows service.])
|
||||
ARG_ENABL_SET([systemd], [enable systemd specific IKE daemon charon-systemd.])
|
||||
@@ -1483,7 +1482,6 @@ charon_plugins=
|
||||
starter_plugins=
|
||||
pool_plugins=
|
||||
attest_plugins=
|
||||
scepclient_plugins=
|
||||
pki_plugins=
|
||||
scripts_plugins=
|
||||
fuzz_plugins=
|
||||
@@ -1500,48 +1498,48 @@ s_plugins=
|
||||
t_plugins=
|
||||
p_plugins=
|
||||
|
||||
ADD_PLUGIN([test-vectors], [s charon scepclient pki])
|
||||
ADD_PLUGIN([test-vectors], [s charon pki])
|
||||
ADD_PLUGIN([unbound], [s charon scripts])
|
||||
ADD_PLUGIN([ldap], [s charon scepclient scripts nm cmd])
|
||||
ADD_PLUGIN([ldap], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([pkcs11], [s charon pki nm cmd])
|
||||
ADD_PLUGIN([tpm], [p charon pki nm cmd])
|
||||
ADD_PLUGIN([aesni], [s charon scepclient pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([aes], [s charon scepclient pki scripts nm cmd])
|
||||
ADD_PLUGIN([des], [s charon scepclient pki scripts nm cmd])
|
||||
ADD_PLUGIN([blowfish], [s charon scepclient pki scripts nm cmd])
|
||||
ADD_PLUGIN([rc2], [s charon scepclient pki scripts nm cmd])
|
||||
ADD_PLUGIN([sha2], [s charon scepclient pki scripts medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([sha3], [s charon scepclient pki scripts medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([sha1], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([md4], [s charon scepclient pki nm cmd])
|
||||
ADD_PLUGIN([md5], [s charon scepclient pki scripts attest nm cmd aikgen])
|
||||
ADD_PLUGIN([mgf1], [s charon scepclient pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([rdrand], [s charon scepclient pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([random], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([aesni], [s charon pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([aes], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([des], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([blowfish], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([rc2], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([sha2], [s charon pki scripts medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([sha3], [s charon pki scripts medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([sha1], [s charon pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([md4], [s charon pki nm cmd])
|
||||
ADD_PLUGIN([md5], [s charon pki scripts attest nm cmd aikgen])
|
||||
ADD_PLUGIN([mgf1], [s charon pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([rdrand], [s charon pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([random], [s charon pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([nonce], [s charon nm cmd aikgen])
|
||||
ADD_PLUGIN([x509], [s charon scepclient pki scripts attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([x509], [s charon pki scripts attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([revocation], [s charon pki nm cmd])
|
||||
ADD_PLUGIN([constraints], [s charon nm cmd])
|
||||
ADD_PLUGIN([acert], [s charon])
|
||||
ADD_PLUGIN([pubkey], [s charon pki cmd aikgen])
|
||||
ADD_PLUGIN([pkcs1], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([pkcs7], [s charon scepclient pki scripts nm cmd])
|
||||
ADD_PLUGIN([pkcs12], [s charon scepclient pki scripts cmd])
|
||||
ADD_PLUGIN([pkcs1], [s charon pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([pkcs7], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([pkcs12], [s charon pki scripts cmd])
|
||||
ADD_PLUGIN([pgp], [s charon])
|
||||
ADD_PLUGIN([dnskey], [s charon pki])
|
||||
ADD_PLUGIN([sshkey], [s charon pki nm cmd])
|
||||
ADD_PLUGIN([dnscert], [c charon])
|
||||
ADD_PLUGIN([ipseckey], [c charon])
|
||||
ADD_PLUGIN([pem], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([pem], [s charon pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([padlock], [s charon])
|
||||
ADD_PLUGIN([openssl], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([wolfssl], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([gcrypt], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([botan], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([pkcs8], [s charon scepclient pki scripts manager medsrv attest nm cmd])
|
||||
ADD_PLUGIN([af-alg], [s charon scepclient pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([openssl], [s charon pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([wolfssl], [s charon pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([gcrypt], [s charon pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([botan], [s charon pki scripts manager medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([pkcs8], [s charon pki scripts manager medsrv attest nm cmd])
|
||||
ADD_PLUGIN([af-alg], [s charon pki scripts medsrv attest nm cmd aikgen])
|
||||
ADD_PLUGIN([fips-prf], [s charon nm cmd])
|
||||
ADD_PLUGIN([gmp], [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([gmp], [s charon pki scripts manager medsrv attest nm cmd aikgen fuzz])
|
||||
ADD_PLUGIN([curve25519], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([agent], [s charon nm cmd])
|
||||
ADD_PLUGIN([keychain], [s charon cmd])
|
||||
@@ -1557,8 +1555,8 @@ ADD_PLUGIN([ntru], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([drbg], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([newhope], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([bliss], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([curl], [s charon scepclient pki scripts nm cmd])
|
||||
ADD_PLUGIN([files], [s charon scepclient pki scripts nm cmd])
|
||||
ADD_PLUGIN([curl], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([files], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([winhttp], [s charon pki scripts])
|
||||
ADD_PLUGIN([soup], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([mysql], [s charon pool manager medsrv attest])
|
||||
@@ -1838,11 +1836,10 @@ AM_CONDITIONAL(USE_ADNS, test x$adns = xtrue)
|
||||
AM_CONDITIONAL(USE_CHARON, test x$charon = xtrue)
|
||||
AM_CONDITIONAL(USE_NM, test x$nm = xtrue)
|
||||
AM_CONDITIONAL(USE_PKI, test x$pki = xtrue)
|
||||
AM_CONDITIONAL(USE_SCEPCLIENT, test x$scepclient = xtrue)
|
||||
AM_CONDITIONAL(USE_SCRIPTS, test x$scripts = xtrue)
|
||||
AM_CONDITIONAL(USE_FUZZING, test x$fuzzing = xtrue)
|
||||
AM_CONDITIONAL(USE_CONFTEST, test x$conftest = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$pki = xtrue -o x$scepclient = xtrue -o x$conftest = xtrue -o x$fast = xtrue -o x$imcv = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$tls = xtrue -o x$tnc_tnccs = xtrue -o x$aikgen = xtrue -o x$svc = xtrue -o x$systemd = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$pki = xtrue -o x$conftest = xtrue -o x$fast = xtrue -o x$imcv = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$tls = xtrue -o x$tnc_tnccs = xtrue -o x$aikgen = xtrue -o x$svc = xtrue -o x$systemd = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBCHARON, test x$charon = xtrue -o x$conftest = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$svc = xtrue -o x$systemd = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBIPSEC, test x$libipsec = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBNTTFFT, test x$bliss = xtrue -o x$newhope = xtrue)
|
||||
@@ -1851,7 +1848,7 @@ AM_CONDITIONAL(USE_LIBTNCCS, test x$tnc_tnccs = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBPTTLS, test x$tnc_tnccs = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBTPMTSS, test x$tss_trousers = xtrue -o x$tss_tss2 = xtrue -o x$tpm = xtrue -o x$aikgen = xtrue -o x$imcv = xtrue)
|
||||
AM_CONDITIONAL(USE_FILE_CONFIG, test x$stroke = xtrue)
|
||||
AM_CONDITIONAL(USE_IPSEC_SCRIPT, test x$stroke = xtrue -o x$scepclient = xtrue -o x$conftest = xtrue)
|
||||
AM_CONDITIONAL(USE_IPSEC_SCRIPT, test x$stroke = xtrue -o x$conftest = xtrue)
|
||||
AM_CONDITIONAL(USE_LIBCAP, test x$capabilities = xlibcap)
|
||||
AM_CONDITIONAL(USE_VSTR, test x$printf_hooks = xvstr)
|
||||
AM_CONDITIONAL(USE_BUILTIN_PRINTF, test x$printf_hooks = xbuiltin)
|
||||
@@ -1927,7 +1924,6 @@ AM_COND_IF([USE_IMV_SWIMA], [strongswan_options=${strongswan_options}" sec-updat
|
||||
AM_COND_IF([USE_LIBTNCCS], [strongswan_options=${strongswan_options}" tnc"])
|
||||
AM_COND_IF([USE_MANAGER], [strongswan_options=${strongswan_options}" manager"])
|
||||
AM_COND_IF([USE_MEDSRV], [strongswan_options=${strongswan_options}" medsrv"])
|
||||
AM_COND_IF([USE_SCEPCLIENT], [strongswan_options=${strongswan_options}" scepclient"])
|
||||
AM_COND_IF([USE_PKI], [strongswan_options=${strongswan_options}" pki"])
|
||||
AM_COND_IF([USE_SWANCTL], [strongswan_options=${strongswan_options}" swanctl"])
|
||||
AM_COND_IF([USE_SYSTEMD], [strongswan_options=${strongswan_options}" charon-systemd"])
|
||||
@@ -2134,7 +2130,6 @@ AC_CONFIG_FILES([
|
||||
src/starter/Makefile
|
||||
src/starter/tests/Makefile
|
||||
src/_updown/Makefile
|
||||
src/scepclient/Makefile
|
||||
src/aikgen/Makefile
|
||||
src/tpm_extendpcr/Makefile
|
||||
src/pki/Makefile
|
||||
|
||||
@@ -75,10 +75,6 @@ if USE_UPDOWN
|
||||
SUBDIRS += _updown
|
||||
endif
|
||||
|
||||
if USE_SCEPCLIENT
|
||||
SUBDIRS += scepclient
|
||||
endif
|
||||
|
||||
if USE_PKI
|
||||
SUBDIRS += pki
|
||||
endif
|
||||
|
||||
@@ -102,10 +102,6 @@ if USE_SYSTEMD
|
||||
exes += $(DESTDIR)$(sbindir)/charon-systemd
|
||||
endif
|
||||
|
||||
if USE_SCEPCLIENT
|
||||
exes += $(DESTDIR)$(ipsecdir)/scepclient
|
||||
endif
|
||||
|
||||
if USE_PKI
|
||||
exes += $(DESTDIR)$(bindir)/pki
|
||||
endif
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
scepclient
|
||||
@@ -1,28 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# copy-n-paste from Makefile.am
|
||||
scepclient_SOURCES := \
|
||||
scepclient.c scep.c scep.h
|
||||
|
||||
LOCAL_SRC_FILES := $(filter %.c,$(scepclient_SOURCES))
|
||||
|
||||
# build scepclient -------------------------------------------------------------
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(strongswan_PATH)/src/libstrongswan
|
||||
|
||||
LOCAL_CFLAGS := $(strongswan_CFLAGS) \
|
||||
-DPLUGINS='"$(strongswan_SCEPCLIENT_PLUGINS)"'
|
||||
|
||||
LOCAL_MODULE := scepclient
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_ARM_MODE := arm
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libstrongswan
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
@@ -1,16 +0,0 @@
|
||||
ipsec_PROGRAMS = scepclient
|
||||
scepclient_SOURCES = \
|
||||
scepclient.c scep.c scep.h
|
||||
|
||||
scepclient.o : $(top_builddir)/config.status
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-DIPSEC_CONFDIR=\"${sysconfdir}\" \
|
||||
-DPLUGINS=\""${scepclient_plugins}\""
|
||||
|
||||
scepclient_LDADD = \
|
||||
$(top_builddir)/src/libstrongswan/libstrongswan.la
|
||||
|
||||
dist_man_MANS = scepclient.8
|
||||
EXTRA_DIST = Android.mk
|
||||
@@ -0,0 +1,18 @@
|
||||
# ipsec scepclient #
|
||||
|
||||
## Description ##
|
||||
|
||||
The `ipsec scepclient` tool was an early client implementation of the
|
||||
_Simple Certificate Enrollment Protocol_ (SCEP).
|
||||
|
||||
The tool was written in 2005 and only got marginal updates since then. Hence it
|
||||
implemented an old version of the SCEP Internet Draft (version 10/11 of
|
||||
`draft-nourse-scep` and used the broken `MD5` hash and single `DES` encryption
|
||||
algorithms as defaults.
|
||||
|
||||
## Obsolescence ##
|
||||
|
||||
With strongSwan version 5.9.8 `*ipsec scepclient*` has been removed and replaced
|
||||
by the `pki` subcommands `pki --scep` and `pki --scepca` which implement the new
|
||||
SCEP RFC 8894 standard that was released in September 2020 and which supports
|
||||
trusted **certificate renewal** based on the existing client certificate.
|
||||
@@ -1,474 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/debug.h>
|
||||
#include <asn1/asn1.h>
|
||||
#include <asn1/asn1_parser.h>
|
||||
#include <asn1/oid.h>
|
||||
#include <crypto/rngs/rng.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
#include "scep.h"
|
||||
|
||||
static const char *pkiStatus_values[] = { "0", "2", "3" };
|
||||
|
||||
static const char *pkiStatus_names[] = {
|
||||
"SUCCESS",
|
||||
"FAILURE",
|
||||
"PENDING",
|
||||
"UNKNOWN"
|
||||
};
|
||||
|
||||
static const char *msgType_values[] = { "3", "19", "20", "21", "22" };
|
||||
|
||||
static const char *msgType_names[] = {
|
||||
"CertRep",
|
||||
"PKCSReq",
|
||||
"GetCertInitial",
|
||||
"GetCert",
|
||||
"GetCRL",
|
||||
"Unknown"
|
||||
};
|
||||
|
||||
static const char *failInfo_reasons[] = {
|
||||
"badAlg - unrecognized or unsupported algorithm identifier",
|
||||
"badMessageCheck - integrity check failed",
|
||||
"badRequest - transaction not permitted or supported",
|
||||
"badTime - Message time field was not sufficiently close to the system time",
|
||||
"badCertId - No certificate could be identified matching the provided criteria"
|
||||
};
|
||||
|
||||
const scep_attributes_t empty_scep_attributes = {
|
||||
SCEP_Unknown_MSG , /* msgType */
|
||||
SCEP_UNKNOWN , /* pkiStatus */
|
||||
SCEP_unknown_REASON, /* failInfo */
|
||||
{ NULL, 0 } , /* transID */
|
||||
{ NULL, 0 } , /* senderNonce */
|
||||
{ NULL, 0 } , /* recipientNonce */
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract X.501 attributes
|
||||
*/
|
||||
void extract_attributes(pkcs7_t *pkcs7, enumerator_t *enumerator,
|
||||
scep_attributes_t *attrs)
|
||||
{
|
||||
chunk_t attr;
|
||||
|
||||
if (pkcs7->get_attribute(pkcs7, OID_PKI_MESSAGE_TYPE, enumerator, &attr))
|
||||
{
|
||||
scep_msg_t m;
|
||||
|
||||
for (m = SCEP_CertRep_MSG; m < SCEP_Unknown_MSG; m++)
|
||||
{
|
||||
if (strncmp(msgType_values[m], attr.ptr, attr.len) == 0)
|
||||
{
|
||||
attrs->msgType = m;
|
||||
}
|
||||
}
|
||||
DBG2(DBG_APP, "messageType: %s", msgType_names[attrs->msgType]);
|
||||
free(attr.ptr);
|
||||
}
|
||||
if (pkcs7->get_attribute(pkcs7, OID_PKI_STATUS, enumerator, &attr))
|
||||
{
|
||||
pkiStatus_t s;
|
||||
|
||||
for (s = SCEP_SUCCESS; s < SCEP_UNKNOWN; s++)
|
||||
{
|
||||
if (strncmp(pkiStatus_values[s], attr.ptr, attr.len) == 0)
|
||||
{
|
||||
attrs->pkiStatus = s;
|
||||
}
|
||||
}
|
||||
DBG2(DBG_APP, "pkiStatus: %s", pkiStatus_names[attrs->pkiStatus]);
|
||||
free(attr.ptr);
|
||||
}
|
||||
if (pkcs7->get_attribute(pkcs7, OID_PKI_FAIL_INFO, enumerator, &attr))
|
||||
{
|
||||
if (attr.len == 1 && *attr.ptr >= '0' && *attr.ptr <= '4')
|
||||
{
|
||||
attrs->failInfo = (failInfo_t)(*attr.ptr - '0');
|
||||
}
|
||||
if (attrs->failInfo != SCEP_unknown_REASON)
|
||||
{
|
||||
DBG1(DBG_APP, "failInfo: %s", failInfo_reasons[attrs->failInfo]);
|
||||
}
|
||||
free(attr.ptr);
|
||||
}
|
||||
|
||||
pkcs7->get_attribute(pkcs7, OID_PKI_SENDER_NONCE, enumerator,
|
||||
&attrs->senderNonce);
|
||||
pkcs7->get_attribute(pkcs7, OID_PKI_RECIPIENT_NONCE, enumerator,
|
||||
&attrs->recipientNonce);
|
||||
pkcs7->get_attribute(pkcs7, OID_PKI_TRANS_ID, enumerator,
|
||||
&attrs->transID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique fingerprint of the pkcs10 request
|
||||
* by computing an MD5 hash over it
|
||||
*/
|
||||
chunk_t scep_generate_pkcs10_fingerprint(chunk_t pkcs10)
|
||||
{
|
||||
chunk_t digest = chunk_alloca(HASH_SIZE_MD5);
|
||||
hasher_t *hasher;
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
|
||||
if (!hasher || !hasher->get_hash(hasher, pkcs10, digest.ptr))
|
||||
{
|
||||
DESTROY_IF(hasher);
|
||||
return chunk_empty;
|
||||
}
|
||||
hasher->destroy(hasher);
|
||||
|
||||
return chunk_to_hex(digest, NULL, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a transaction id as the MD5 hash of an public key
|
||||
* the transaction id is also used as a unique serial number
|
||||
*/
|
||||
void scep_generate_transaction_id(public_key_t *key, chunk_t *transID,
|
||||
chunk_t *serialNumber)
|
||||
{
|
||||
chunk_t digest = chunk_alloca(HASH_SIZE_MD5);
|
||||
chunk_t keyEncoding = chunk_empty, keyInfo;
|
||||
hasher_t *hasher;
|
||||
int zeros = 0, msb_set = 0;
|
||||
|
||||
key->get_encoding(key, PUBKEY_ASN1_DER, &keyEncoding);
|
||||
|
||||
keyInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||
asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
|
||||
asn1_bitstring("m", keyEncoding));
|
||||
|
||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
|
||||
if (!hasher || !hasher->get_hash(hasher, keyInfo, digest.ptr))
|
||||
{
|
||||
memset(digest.ptr, 0, digest.len);
|
||||
}
|
||||
DESTROY_IF(hasher);
|
||||
free(keyInfo.ptr);
|
||||
|
||||
/* the serialNumber should be valid ASN1 integer content:
|
||||
* remove leading zeros, add one if MSB is set (two's complement) */
|
||||
while (zeros < digest.len)
|
||||
{
|
||||
if (digest.ptr[zeros])
|
||||
{
|
||||
if (digest.ptr[zeros] & 0x80)
|
||||
{
|
||||
msb_set = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
zeros++;
|
||||
}
|
||||
*serialNumber = chunk_alloc(digest.len - zeros + msb_set);
|
||||
if (msb_set)
|
||||
{
|
||||
serialNumber->ptr[0] = 0x00;
|
||||
}
|
||||
memcpy(serialNumber->ptr + msb_set, digest.ptr + zeros,
|
||||
digest.len - zeros);
|
||||
|
||||
/* the transaction id is the serial number in hex format */
|
||||
*transID = chunk_to_hex(digest, NULL, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a pkcs7 enveloped and signed scep request
|
||||
*/
|
||||
chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
|
||||
certificate_t *enc_cert, encryption_algorithm_t enc_alg,
|
||||
size_t key_size, certificate_t *signer_cert,
|
||||
hash_algorithm_t digest_alg, private_key_t *private_key)
|
||||
{
|
||||
chunk_t request;
|
||||
container_t *container;
|
||||
char nonce[16];
|
||||
rng_t *rng;
|
||||
chunk_t senderNonce, msgType;
|
||||
|
||||
/* generate senderNonce */
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
|
||||
if (!rng || !rng->get_bytes(rng, sizeof(nonce), nonce))
|
||||
{
|
||||
DESTROY_IF(rng);
|
||||
return chunk_empty;
|
||||
}
|
||||
rng->destroy(rng);
|
||||
|
||||
/* encrypt data in enveloped-data PKCS#7 */
|
||||
container = lib->creds->create(lib->creds,
|
||||
CRED_CONTAINER, CONTAINER_PKCS7_ENVELOPED_DATA,
|
||||
BUILD_BLOB, data,
|
||||
BUILD_CERT, enc_cert,
|
||||
BUILD_ENCRYPTION_ALG, enc_alg,
|
||||
BUILD_KEY_SIZE, (int)key_size,
|
||||
BUILD_END);
|
||||
if (!container)
|
||||
{
|
||||
return chunk_empty;
|
||||
}
|
||||
if (!container->get_encoding(container, &request))
|
||||
{
|
||||
container->destroy(container);
|
||||
return chunk_empty;
|
||||
}
|
||||
container->destroy(container);
|
||||
|
||||
/* sign enveloped-data in a signed-data PKCS#7 */
|
||||
senderNonce = asn1_wrap(ASN1_OCTET_STRING, "c", chunk_from_thing(nonce));
|
||||
transID = asn1_wrap(ASN1_PRINTABLESTRING, "c", transID);
|
||||
msgType = asn1_wrap(ASN1_PRINTABLESTRING, "c",
|
||||
chunk_create((char*)msgType_values[msg],
|
||||
strlen(msgType_values[msg])));
|
||||
|
||||
container = lib->creds->create(lib->creds,
|
||||
CRED_CONTAINER, CONTAINER_PKCS7_SIGNED_DATA,
|
||||
BUILD_BLOB, request,
|
||||
BUILD_SIGNING_CERT, signer_cert,
|
||||
BUILD_SIGNING_KEY, private_key,
|
||||
BUILD_DIGEST_ALG, digest_alg,
|
||||
BUILD_PKCS7_ATTRIBUTE, OID_PKI_SENDER_NONCE, senderNonce,
|
||||
BUILD_PKCS7_ATTRIBUTE, OID_PKI_TRANS_ID, transID,
|
||||
BUILD_PKCS7_ATTRIBUTE, OID_PKI_MESSAGE_TYPE, msgType,
|
||||
BUILD_END);
|
||||
|
||||
free(request.ptr);
|
||||
free(senderNonce.ptr);
|
||||
free(transID.ptr);
|
||||
free(msgType.ptr);
|
||||
|
||||
if (!container)
|
||||
{
|
||||
return chunk_empty;
|
||||
}
|
||||
if (!container->get_encoding(container, &request))
|
||||
{
|
||||
container->destroy(container);
|
||||
return chunk_empty;
|
||||
}
|
||||
container->destroy(container);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a binary request to base64 with 64 characters per line
|
||||
* newline and '+' characters are escaped by %0A and %2B, respectively
|
||||
*/
|
||||
static char* escape_http_request(chunk_t req)
|
||||
{
|
||||
char *escaped_req = NULL;
|
||||
char *p1, *p2;
|
||||
int lines = 0;
|
||||
int plus = 0;
|
||||
int n = 0;
|
||||
|
||||
/* compute and allocate the size of the base64-encoded request */
|
||||
int len = 1 + 4 * ((req.len + 2) / 3);
|
||||
char *encoded_req = malloc(len);
|
||||
|
||||
/* do the base64 conversion */
|
||||
chunk_t base64 = chunk_to_base64(req, encoded_req);
|
||||
len = base64.len + 1;
|
||||
|
||||
/* compute newline characters to be inserted every 64 characters */
|
||||
lines = (len - 2) / 64;
|
||||
|
||||
/* count number of + characters to be escaped */
|
||||
p1 = encoded_req;
|
||||
while (*p1 != '\0')
|
||||
{
|
||||
if (*p1++ == '+')
|
||||
{
|
||||
plus++;
|
||||
}
|
||||
}
|
||||
|
||||
escaped_req = malloc(len + 3 * (lines + plus));
|
||||
|
||||
/* escape special characters in the request */
|
||||
p1 = encoded_req;
|
||||
p2 = escaped_req;
|
||||
while (*p1 != '\0')
|
||||
{
|
||||
if (n == 64)
|
||||
{
|
||||
memcpy(p2, "%0A", 3);
|
||||
p2 += 3;
|
||||
n = 0;
|
||||
}
|
||||
if (*p1 == '+')
|
||||
{
|
||||
memcpy(p2, "%2B", 3);
|
||||
p2 += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p2++ = *p1;
|
||||
}
|
||||
p1++;
|
||||
n++;
|
||||
}
|
||||
*p2 = '\0';
|
||||
free(encoded_req);
|
||||
return escaped_req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a SCEP request via HTTP and wait for a response
|
||||
*/
|
||||
bool scep_http_request(const char *url, chunk_t msg, scep_op_t op,
|
||||
bool http_get_request, u_int timeout, char *src,
|
||||
chunk_t *response)
|
||||
{
|
||||
int len;
|
||||
status_t status;
|
||||
char *complete_url = NULL;
|
||||
host_t *srcip = NULL;
|
||||
|
||||
/* initialize response */
|
||||
*response = chunk_empty;
|
||||
|
||||
if (src)
|
||||
{
|
||||
srcip = host_create_from_string(src, 0);
|
||||
}
|
||||
|
||||
DBG2(DBG_APP, "sending scep request to '%s'", url);
|
||||
|
||||
if (op == SCEP_PKI_OPERATION)
|
||||
{
|
||||
const char operation[] = "PKIOperation";
|
||||
|
||||
if (http_get_request)
|
||||
{
|
||||
char *escaped_req = escape_http_request(msg);
|
||||
|
||||
/* form complete url */
|
||||
len = strlen(url) + 20 + strlen(operation) + strlen(escaped_req) + 1;
|
||||
complete_url = malloc(len);
|
||||
snprintf(complete_url, len, "%s?operation=%s&message=%s"
|
||||
, url, operation, escaped_req);
|
||||
free(escaped_req);
|
||||
|
||||
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
||||
FETCH_HTTP_VERSION_1_0,
|
||||
FETCH_TIMEOUT, timeout,
|
||||
FETCH_REQUEST_HEADER, "Pragma:",
|
||||
FETCH_REQUEST_HEADER, "Host:",
|
||||
FETCH_REQUEST_HEADER, "Accept:",
|
||||
FETCH_SOURCEIP, srcip,
|
||||
FETCH_END);
|
||||
}
|
||||
else /* HTTP_POST */
|
||||
{
|
||||
/* form complete url */
|
||||
len = strlen(url) + 11 + strlen(operation) + 1;
|
||||
complete_url = malloc(len);
|
||||
snprintf(complete_url, len, "%s?operation=%s", url, operation);
|
||||
|
||||
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
||||
FETCH_HTTP_VERSION_1_0,
|
||||
FETCH_TIMEOUT, timeout,
|
||||
FETCH_REQUEST_DATA, msg,
|
||||
FETCH_REQUEST_TYPE, "",
|
||||
FETCH_REQUEST_HEADER, "Expect:",
|
||||
FETCH_SOURCEIP, srcip,
|
||||
FETCH_END);
|
||||
}
|
||||
}
|
||||
else /* SCEP_GET_CA_CERT */
|
||||
{
|
||||
const char operation[] = "GetCACert";
|
||||
int i;
|
||||
|
||||
/* escape spaces, TODO: complete URL escape */
|
||||
for (i = 0; i < msg.len; i++)
|
||||
{
|
||||
if (msg.ptr[i] == ' ')
|
||||
{
|
||||
msg.ptr[i] = '+';
|
||||
}
|
||||
}
|
||||
|
||||
/* form complete url */
|
||||
len = strlen(url) + 32 + strlen(operation) + msg.len + 1;
|
||||
complete_url = malloc(len);
|
||||
snprintf(complete_url, len, "%s?operation=%s&message=%.*s",
|
||||
url, operation, (int)msg.len, msg.ptr);
|
||||
|
||||
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
|
||||
FETCH_HTTP_VERSION_1_0,
|
||||
FETCH_TIMEOUT, timeout,
|
||||
FETCH_SOURCEIP, srcip,
|
||||
FETCH_END);
|
||||
}
|
||||
|
||||
DESTROY_IF(srcip);
|
||||
free(complete_url);
|
||||
return (status == SUCCESS);
|
||||
}
|
||||
|
||||
err_t scep_parse_response(chunk_t response, chunk_t transID,
|
||||
container_t **out, scep_attributes_t *attrs)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
bool verified = FALSE;
|
||||
container_t *container;
|
||||
auth_cfg_t *auth;
|
||||
|
||||
container = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS7,
|
||||
BUILD_BLOB_ASN1_DER, response, BUILD_END);
|
||||
if (!container)
|
||||
{
|
||||
return "error parsing the scep response";
|
||||
}
|
||||
if (container->get_type(container) != CONTAINER_PKCS7_SIGNED_DATA)
|
||||
{
|
||||
container->destroy(container);
|
||||
return "scep response is not PKCS#7 signed-data";
|
||||
}
|
||||
|
||||
enumerator = container->create_signature_enumerator(container);
|
||||
while (enumerator->enumerate(enumerator, &auth))
|
||||
{
|
||||
verified = TRUE;
|
||||
extract_attributes((pkcs7_t*)container, enumerator, attrs);
|
||||
if (!chunk_equals(transID, attrs->transID))
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
container->destroy(container);
|
||||
return "transaction ID of scep response does not match";
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!verified)
|
||||
{
|
||||
container->destroy(container);
|
||||
return "unable to verify PKCS#7 container";
|
||||
}
|
||||
*out = container;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
*
|
||||
* Copyright (C) secunet Security Networks AG
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SCEP_H
|
||||
#define _SCEP_H
|
||||
|
||||
#include <credentials/containers/pkcs7.h>
|
||||
#include <credentials/certificates/certificate.h>
|
||||
|
||||
/* supported SCEP operation types */
|
||||
typedef enum {
|
||||
SCEP_PKI_OPERATION,
|
||||
SCEP_GET_CA_CERT
|
||||
} scep_op_t;
|
||||
|
||||
/* SCEP pkiStatus values */
|
||||
typedef enum {
|
||||
SCEP_SUCCESS,
|
||||
SCEP_FAILURE,
|
||||
SCEP_PENDING,
|
||||
SCEP_UNKNOWN
|
||||
} pkiStatus_t;
|
||||
|
||||
/* SCEP messageType values */
|
||||
typedef enum {
|
||||
SCEP_CertRep_MSG,
|
||||
SCEP_PKCSReq_MSG,
|
||||
SCEP_GetCertInitial_MSG,
|
||||
SCEP_GetCert_MSG,
|
||||
SCEP_GetCRL_MSG,
|
||||
SCEP_Unknown_MSG
|
||||
} scep_msg_t;
|
||||
|
||||
/* SCEP failure reasons */
|
||||
typedef enum {
|
||||
SCEP_badAlg_REASON = 0,
|
||||
SCEP_badMessageCheck_REASON = 1,
|
||||
SCEP_badRequest_REASON = 2,
|
||||
SCEP_badTime_REASON = 3,
|
||||
SCEP_badCertId_REASON = 4,
|
||||
SCEP_unknown_REASON = 5
|
||||
} failInfo_t;
|
||||
|
||||
/* SCEP attributes */
|
||||
typedef struct {
|
||||
scep_msg_t msgType;
|
||||
pkiStatus_t pkiStatus;
|
||||
failInfo_t failInfo;
|
||||
chunk_t transID;
|
||||
chunk_t senderNonce;
|
||||
chunk_t recipientNonce;
|
||||
} scep_attributes_t;
|
||||
|
||||
extern const scep_attributes_t empty_scep_attributes;
|
||||
|
||||
bool parse_attributes(chunk_t blob, scep_attributes_t *attrs);
|
||||
void scep_generate_transaction_id(public_key_t *key,
|
||||
chunk_t *transID,
|
||||
chunk_t *serialNumber);
|
||||
chunk_t scep_generate_pkcs10_fingerprint(chunk_t pkcs10);
|
||||
chunk_t scep_transId_attribute(chunk_t transaction_id);
|
||||
chunk_t scep_messageType_attribute(scep_msg_t m);
|
||||
chunk_t scep_senderNonce_attribute(void);
|
||||
chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
|
||||
certificate_t *enc_cert, encryption_algorithm_t enc_alg,
|
||||
size_t key_size, certificate_t *signer_cert,
|
||||
hash_algorithm_t digest_alg, private_key_t *private_key);
|
||||
bool scep_http_request(const char *url, chunk_t msg, scep_op_t op,
|
||||
bool http_get_request, u_int timeout, char *src,
|
||||
chunk_t *response);
|
||||
err_t scep_parse_response(chunk_t response, chunk_t transID,
|
||||
container_t **out, scep_attributes_t *attrs);
|
||||
|
||||
#endif /* _SCEP_H */
|
||||
@@ -1,293 +0,0 @@
|
||||
.\"
|
||||
.TH "IPSEC_SCEPCLIENT" "8" "2012-05-11" "strongSwan" ""
|
||||
.SH "NAME"
|
||||
ipsec scepclient \- Client for the SCEP protocol
|
||||
.SH "SYNOPSIS"
|
||||
.B ipsec scepclient [argument ...]
|
||||
.sp
|
||||
.B ipsec scepclient
|
||||
.B \-\-help
|
||||
.br
|
||||
.B ipsec scepclient
|
||||
.B \-\-version
|
||||
.SH "DESCRIPTION"
|
||||
.BR scepclient
|
||||
is a client implementation of Cisco System's Simple Certificate Enrollment Protocol (SCEP) written for Linux strongSwan <http://www.strongswan.org>.
|
||||
.BR scepclient
|
||||
is designed to be used for certificate enrollment on machines using the OpenSource IPsec solution
|
||||
.I strongSwan.
|
||||
.SH "FEATURES"
|
||||
.BR scepclient
|
||||
implements the following features of SCEP:
|
||||
.br
|
||||
.IP "\-" 4
|
||||
Automatic enrollment of client certificate using a preshared secret
|
||||
.IP "\-" 4
|
||||
Manual enrollment of client certificate. Offline fingerprint check required!
|
||||
.IP "\-" 4
|
||||
Acquisition of CA certificate(s)
|
||||
.SH "OPTIONS"
|
||||
.SS Basic Startup Options
|
||||
.B \-v, \-\-version
|
||||
.RS 4
|
||||
Display the version of ipsec scepclient.
|
||||
.PP
|
||||
.RE
|
||||
.B \-h, \-\-help
|
||||
.RS 4
|
||||
Display usage of ipsec scepclient.
|
||||
.RE
|
||||
|
||||
.SS General Options
|
||||
.B \-u, \-\-url \fIurl\fP
|
||||
.RS 4
|
||||
Full HTTP URL of the SCEP server to be used for certificate enrollment and CA certificate acquisition.
|
||||
.RE
|
||||
.PP
|
||||
.B \-+, \-\-optionsfrom \fIfilename\fP
|
||||
.RS 4
|
||||
Reads additional options from \fIfilename\fP.
|
||||
.RE
|
||||
.PP
|
||||
.B \-f, \-\-force
|
||||
.RS 4
|
||||
Overwrite existing output file[s].
|
||||
.RE
|
||||
.PP
|
||||
.B \-q, \-\-quiet
|
||||
.RS 4
|
||||
Do not write log output to stderr.
|
||||
.RE
|
||||
|
||||
.SS Options for CA Certificate Acquisition
|
||||
.B \-o, \-\-out cacert[=\fIfilename\fP]
|
||||
.RS 4
|
||||
Output file of acquired CA certificate. If more then one CA certificate is
|
||||
available, \fIfilename\fP is used as prefix for the resulting files (refer to
|
||||
EXAMPLES below for details).
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/cacerts/caCert.der.
|
||||
.RE
|
||||
|
||||
.SS Options For Certificate Enrollment
|
||||
.B \-i, \-\-in \fItype\fP[=\fIfilename\fP]
|
||||
.RS 4
|
||||
Input file for certificate enrollment. This option can be specified multiple times to specify input files for every \fItype\fP.
|
||||
Input files can be either DER or PEM encoded.
|
||||
.PP
|
||||
Supported values for \fItype\fP:
|
||||
.IP "\fBpkcs1\fP" 12
|
||||
RSA private key in PKCS#1 file format. If no input of this type is specified, a RSA key gets generated.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/private/myKey.der.
|
||||
.IP "\fBpkcs10\fP" 12
|
||||
PKCS#10 certificate request to be used in the SCEP request. If no input of this type is specified, a request is generated.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/req/myReq.der.
|
||||
.IP "\fBcacert\-enc\fP" 12
|
||||
CA certificate to encrypt the SCEP request. Has to be specified for certificate enrollment.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/cacerts/caCert.der.
|
||||
.IP "\fBcacert\-sig\fP" 12
|
||||
CA certificate to check signature of SCEP reply. Has to be specified for certificate enrollment.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/cacerts/caCert.der.
|
||||
.IP "\fBcert-self\fP" 12
|
||||
Certificate to be used in the SCEP request. If it is not specified a
|
||||
self-signed certificate is generated automatically.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/certs/selfCert.der.
|
||||
.RE
|
||||
.PP
|
||||
.B \-k, \-\-keylength \fIbits\fP
|
||||
.RS 4
|
||||
sets the key length for RSA key generation. The default length for a generated rsa key is set to 2048 bit.
|
||||
.RE
|
||||
.PP
|
||||
.B \-D, \-\-days \fIdays\fP
|
||||
.RS 4
|
||||
Validity of the self-signed X.509 certificate in days. The default is 1825 days (5 years).
|
||||
.RE
|
||||
.PP
|
||||
.B \-S, \-\-startdate \fIYYMMDDHHMMSS\fPZ
|
||||
.RS 4
|
||||
defines the \fBnotBefore\fP date when the X.509 certificate becomes valid.
|
||||
The date has the format \fIYYMMDDHHMMSS\fP and must be specified in UTC (Zulu time).
|
||||
If the \fB--startdate\fP option is not specified then the current date is taken as a default.
|
||||
.RE
|
||||
.PP
|
||||
.B \-E, \-\-enddate \fIYYMMDDHHMMSS\fPZ
|
||||
.RS 4
|
||||
defines the \fBnotAfter\fP date when the X.509 certificate will expire.
|
||||
The date has the format \fIYYMMDDHHMMSS\fP and must be specified in UTC (Zulu time).
|
||||
If the \fB--enddate\fP option is not specified then the default \fBnotAfter\fP value is computed by
|
||||
adding the validity interval specified by the \fB--days\fP option to the \fBnotBefore\fP date.
|
||||
.RE
|
||||
.PP
|
||||
.B \-d, \-\-dn \fIdn\fP
|
||||
.RS 4
|
||||
Distinguished name as comma separated list of relative distinguished names. Use quotation marks for a distinguished name containing spaces. If the \fB\-\-dn\fP parameter is missing then the default "C=CH, O=Linux strongSwan, CN=\fIhostname\fP"
|
||||
is used with \fIhostname\fP being the return value of the \fIgethostname\fP() function.
|
||||
.RE
|
||||
.PP
|
||||
.B \-s, \-\-subjectAltName \fItype\fP=\fIvalue\fP
|
||||
.RS 4
|
||||
Include subjectAltName in certificate request. This option can be specified multiple times to specify a subjectAltName
|
||||
for every \fItype\fP.
|
||||
.PP
|
||||
Supported values for \fItype\fP:
|
||||
.IP "\fBemail\fP" 12
|
||||
subjectAltName is a email address.
|
||||
.IP "\fBdns\fP" 12
|
||||
subjectAltName is a hostname.
|
||||
.IP "\fBip\fP" 12
|
||||
subjectAltName is a IP address.
|
||||
.RE
|
||||
.PP
|
||||
.B \-p, \-\-password \fIpw\fP
|
||||
.RS 4
|
||||
Password to be included as a \fIchallenge password\fP in SCEP request.
|
||||
If \fIpw\fP is \fB%prompt\fP', the password gets prompted for on the command line.
|
||||
.IP
|
||||
\- In automatic mode, this password corresponds to the preshared secret for the given enrollment.
|
||||
.IP
|
||||
\- In manual mode, this password can be used to later revoke the corresponding certificate.
|
||||
.RE
|
||||
.PP
|
||||
.B \-a, \-\-algorithm [\fItype\fP=]\fIalgo\fP
|
||||
.RS 4
|
||||
Change the algorithms to be used when generating and transporting (PKCS#7)
|
||||
certificate requests (PKCS#10).
|
||||
.PP
|
||||
Supported values for \fItype\fP:
|
||||
.IP "\fBenc\fP" 12
|
||||
symmetric encryption algorithm in PKCS#7
|
||||
.IP "\fBdgst\fP" 12
|
||||
hash algorithm for message digest in PKCS#7
|
||||
.IP "\fBsig\fP" 12
|
||||
hash algorithm for the signature in PKCS#10
|
||||
.PP
|
||||
If \fItype\fP is not specified \fBenc\fP is assumed.
|
||||
.PP
|
||||
Supported values for \fIalgo\fP (\fBenc\fP):
|
||||
.IP "\fBdes\fP" 12
|
||||
DES-CBC encryption (key size = 56 bit). Default.
|
||||
.IP "\fB3des\fP" 12
|
||||
Triple DES-EDE-CBC encryption (key size = 168 bit).
|
||||
.IP "\fBaes128\fP" 12
|
||||
AES-CBC encryption (key size = 128 bit).
|
||||
.IP "\fBaes192\fP" 12
|
||||
AES-CBC encryption (key size = 192 bit).
|
||||
.IP "\fBaes256\fP" 12
|
||||
AES-CBC encryption (key size = 256 bit).
|
||||
.IP "\fBcamellia128\fP" 12
|
||||
Camellia-CBC encryption (key size = 128 bit).
|
||||
.IP "\fBcamellia192\fP" 12
|
||||
Camellia-CBC encryption (key size = 192 bit).
|
||||
.IP "\fBcamellia256\fP" 12
|
||||
Camellia-CBC encryption (key size = 256 bit).
|
||||
.PP
|
||||
Supported values for \fIalgo\fP (\fBdgst\fP or \fBsig\fP):
|
||||
.PP
|
||||
\fBmd5\fP (default), \fBsha1\fP, \fBsha256\fP, \fBsha384\fP, \fBsha512\fP
|
||||
.RE
|
||||
.PP
|
||||
.B \-o, \-\-out \fItype\fP[=\fIfilename\fP]
|
||||
.RS 4
|
||||
Output file for certificate enrollment. This option can be specified multiple times to specify output files for every \fItype\fP.
|
||||
.PP
|
||||
Supported values for \fItype\fP:
|
||||
.IP "\fBpkcs1\fP" 12
|
||||
RSA private key in PKCS#1 file format. If specified, the RSA key used for enrollment is stored in file \fIfilename\fP.
|
||||
If none of the \fItypes\fP listed below are specified, \fBscepclient\fP will stop after outputting this file.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/private/myKey.der.
|
||||
.IP "\fBpkcs10\fP" 12
|
||||
PKCS#10 certificate request. If specified, the PKCS#10 request used or certificate enrollment is stored in file \fIfilename\fP.
|
||||
If none of the \fItypes\fP listed below are specified, \fBscepclient\fP will stop after outputting this file.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/req/myReq.der.
|
||||
.IP "\fBpkcs7\fP" 12
|
||||
PKCS#7 SCEP request as it is sent using HTTP to the SCEP server. If specified, this SCEP request is stored in file \fIfilename\fP.
|
||||
If none of \fItypes\fP listed below is not specified, \fBscepclient\fP will stop after outputting this file.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/req/pkcs7.der.
|
||||
.IP "\fBcert-self\fP" 12
|
||||
Self-signed certificate. If specified the self-signed certificate is stored in file \fIfilename\fP.
|
||||
.br
|
||||
The default \fIfilename\fP is $CONFDIR/ipsec.d/certs/selfCert.der.
|
||||
.IP "\fBcert\fP" 12
|
||||
Enrolled certificate. This \fItype\fP must be specified for certificate enrollment.
|
||||
The enrolled certificate is stored in file \fIfilename\fP.
|
||||
.br
|
||||
The default \fIfilename\fP is set to $CONFDIR/ipsec.d/certs/myCert.der.
|
||||
.RE
|
||||
.PP
|
||||
.B \-m, \-\-method \fImethod\fP
|
||||
.RS 4
|
||||
Change HTTP request method for certificate enrollment. Default is \fBget\fP.
|
||||
.PP
|
||||
Supported values for \fImethod\fP:
|
||||
.IP "\fBpost\fP" 12
|
||||
Certificate enrollment using HTTP POST. Must be supported by the given SCEP server.
|
||||
.IP "\fBget\fP" 12
|
||||
Certificate enrollment using HTTP GET.
|
||||
.RE
|
||||
.PP
|
||||
.B \-t, \-\-interval \fIseconds\fP
|
||||
.RS 4
|
||||
Set interval time in seconds when polling in manual mode.
|
||||
The default interval is set to 5 seconds.
|
||||
.RE
|
||||
.PP
|
||||
.B \-x, \-\-maxpolltime \fIseconds\fP
|
||||
.RS 4
|
||||
Set max time in seconds to poll in manual mode.
|
||||
The default max time is set to unlimited.
|
||||
.RE
|
||||
|
||||
.SS Debugging Output Options:
|
||||
.B \-l, \-\-debug \fIlevel\fP
|
||||
.RS 4
|
||||
Changes the log level (-1..4, default: 1)
|
||||
.RE
|
||||
.SH "EXAMPLES"
|
||||
.B ipsec scepclient \-\-out caCert \-\-url http://scepserver/cgi\-bin/pkiclient.exe \-f
|
||||
.RS 4
|
||||
Acquire CA certificate from SCEP server and store it in the default file $CONFDIR/ipsec.d/cacerts/caCert.der.
|
||||
If more then one CA certificate is returned, store them in files named
|
||||
\'caCert\-1.der\', \'caCert\-2.der\', etc.
|
||||
If an RA certificate is returned, store it in a file named \'caCert\-ra.der\'.
|
||||
If more than one RA certificate is returned, store them in files named
|
||||
\'caCert\-ra\-1.der\', \'caCert\-ra\-2.der\', etc.
|
||||
.RE
|
||||
.PP
|
||||
.B ipsec scepclient \-\-out pkcs1=joeKey.der \-k 1024
|
||||
.RS 4
|
||||
Generate RSA private key with key length of 1024 bit and store it in file joeKey.der.
|
||||
.RE
|
||||
.PP
|
||||
.B ipsec scepclient \-\-in pkcs1=joeKey.der \-\-out pkcs10=joeReq.der \e
|
||||
.br
|
||||
.B \-\-dn \*(rqC=AT, CN=John Doe\*(rq \-s [email protected] \-p mypassword
|
||||
.RS 4
|
||||
Generate a PKCS#10 request and store it in file joeReq.der. Use the RSA private key joeKey.der
|
||||
created earlier to sign the PKCS#10\-Request. In addition to the distinguished name include a
|
||||
email\-subjectAltName and a challenge password in the request.
|
||||
.RE
|
||||
.PP
|
||||
.B ipsec scepclient \-\-out pkcs1=joeKey.der \-\-out cert==joeCert.der \e
|
||||
.br
|
||||
.B \-\-dn \*(rqC=CH, CN=John Doe\*(rq \-k 512 \-p 5xH2pnT7wq \e
|
||||
.br
|
||||
.B \-\-url http://scep.hsr.ch/cgi\-bin/pkiclient.exe \e
|
||||
.br
|
||||
.B \-\-in cacert\-enc=caCert.der \-\-in cacert\-sig=caCert.der
|
||||
.RS 4
|
||||
Generate a new RSA key for the request and store it in joeKey.der. Then enroll a certificate and store as joeCert.der.
|
||||
The challenge password is '5xH2pnT7wq'. The encryption and signature check has to be made with the same CA certificate
|
||||
caCert.der.
|
||||
.RE
|
||||
|
||||
.SH "BUGS"
|
||||
\fB\-\-optionsfrom\fP seems to have parsing problems reading option files containing strings in quotation marks.
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user