Permalink
Browse files

Added developments from Nimbus and updated README: 1) Can create Java…

… key store (JKS) from X509, 2) empty CRL can now be created which helps with some software that fails without one
  • Loading branch information...
1 parent 3303eea commit b86298e7010e375c9734bb7f80b4031b4d845e61 @timf timf committed Jun 16, 2010
View
35 README
@@ -21,24 +21,35 @@ Usage example of the bin/ samples:
# Create CA cert/key
-CA_BASENAME=fakeca
-mkdir /tmp/123
-./bin/create-ca.sh /tmp/123 $CA_BASENAME
+CA_BASENAME=testca
+mkdir /tmp/ezpz_test
+./bin/create-ca.sh /tmp/ezpz_test $CA_BASENAME
# Create a trusted certificate directory with expected file names
-CA_HASH=`openssl x509 -hash -noout -in /tmp/123/$CA_BASENAME.0`
-CA_PUB=$CAHASH.0
-CA_SP=$CAHASH.signing_policy
-mkdir /tmp/trusted-certs
-cp /tmp/123/$CA_BASENAME.0 /tmp/trusted-certs/$CA_PUB
-cp /tmp/123/$CA_BASENAME.signing_policy /tmp/trusted-certs/$CA_SP
+mkdir /tmp/ezpz_test/trusted-certs
+CA_HASH=`openssl x509 -hash -noout -in /tmp/ezpz_test/$CA_BASENAME.0`
+CA_PUB="/tmp/ezpz_test/trusted-certs/$CA_HASH.0"
+CA_SP="/tmp/ezpz_test/trusted-certs/$CA_HASH.signing_policy"
+cp /tmp/ezpz_test/$CA_BASENAME.0 $CA_PUB
+cp /tmp/ezpz_test/$CA_BASENAME.signing_policy $CA_SP
# Create a cert
-CAPRIV=/tmp/123/private-key-$CA_BASENAME.pem
+CA_PRIV=/tmp/ezpz_test/private-key-$CA_BASENAME.pem
HOSTNAME=example.com
-mkdir /tmp/hostcertdir
-./bin/create-cert.sh /tmp/hostcertdir $HOSTNAME hostcert.pem hostkey.pem $CA_PUB $CAPRIV
+mkdir /tmp/ezpz_test/hostcertdir
+./bin/create-cert.sh /tmp/ezpz_test/hostcertdir $HOSTNAME hostcert.pem hostkey.pem $CA_PUB $CA_PRIV
+
+
+# Create a JKS keystore for the host cert
+
+HOSTCERT=/tmp/ezpz_test/hostcertdir/hostcert.pem
+HOSTKEY=/tmp/ezpz_test/hostcertdir/hostkey.pem
+JKS_TO_CREATE=/tmp/ezpz_test/hostcertdir/hostcert.jks
+JKS_PASSWORD="3con12oij32d"
+
+./bin/create-jks.sh $HOSTCERT $HOSTKEY $JKS_TO_CREATE $JKS_PASSWORD
+
View
@@ -12,17 +12,20 @@ source $LIBDIR/common-env.sh
if [ ! -d $1 ]; then
echo "Directory does not exist: $1" >&2
+ echo "See README" >&2
exit 1
fi
$JAVA_BIN $JAVA_OPTS $EXE_CREATE_NEW_CA $1 $2
if [ $? -ne 0 ]; then
echo "Problem creating new certificate authority, exiting." >&2
+ echo "See README" >&2
exit 1
fi
CA_PUBPEM="$1/$2.pem"
CA_PUBPEM2="$1/$2.0"
+CA_CRL="$1/$2.r0"
CA_SIGNING_POLICY="$1/$2.signing_policy"
CA_PRIVPEM="$1/private-key-$2.pem"
@@ -38,6 +41,12 @@ if [ $? -ne 0 ]; then
exit 1
fi
+$JAVA_BIN $JAVA_OPTS $EXE_CREATE_CRL $CA_CRL $CA_PUBPEM $CA_PRIVPEM
+if [ $? -ne 0 ]; then
+ echo "Problem creating new certificate authority revocation list, exiting." >&2
+ exit 1
+fi
+
cp $CA_PUBPEM $CA_PUBPEM2
if [ $? -ne 0 ]; then
echo "Problem creating certificate authority, exiting." >&2
View
@@ -8,6 +8,11 @@ if [ ! -f $LIBDIR/common-env.sh ]; then
fi
source $LIBDIR/common-env.sh
+if [ $# -ne 6 ]; then
+ echo "Not enough arguments, see README" >&2
+ exit 1
+fi
+
TARGET_DIR=$1
NEW_CN=$2
PUBPEM=$3
@@ -20,15 +25,15 @@ PRIVCA=$6
HOSTDN=`$JAVA_BIN $JAVA_OPTS $EXE_CREATE_NEW_CERT $TARGET_DIR $NEW_CN $PUBPEM $PRIVPEM $PUBCA $PRIVCA`
if [ $? -ne 0 ]; then
- echo "Problem creating cert, exiting."
+ echo "Problem creating cert, exiting." >&2
exit 1
fi
NEW_PRIVPEM="$TARGET_DIR/$PRIVPEM"
chmod 400 $NEW_PRIVPEM
if [ $? -ne 0 ]; then
- echo "Problem setting permissions on $NEW_PRIVPEM"
+ echo "Problem setting permissions on $NEW_PRIVPEM" >&2
exit 1
fi
View
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+THISDIR="`dirname $0`"
+LIBDIR="$THISDIR/../etc/"
+if [ ! -f $LIBDIR/common-env.sh ]; then
+ echo "Failure, cannot find environment definitions" >&2
+ exit 1
+fi
+source $LIBDIR/common-env.sh
+
+if [ $# -ne 4 ]; then
+ echo "Not enough arguments, see README" >&2
+ exit 1
+fi
+
+CERT_PATH=$1
+KEY_PATH=$2
+STORE_PATH=$3
+PASSWORD=$4
+
+# ----------------------------------------------------------------------------
+
+$JAVA_BIN $JAVA_OPTS $EXE_KEYSTORE_FROM_PEM $CERT_PATH $KEY_PATH $STORE_PATH $PASSWORD
+if [ $? -ne 0 ]; then
+ echo "Problem creating keystore, exiting." >&2
+ exit 1
+fi
+
+chmod 600 $STORE_PATH
+if [ $? -ne 0 ]; then
+ echo "Problem setting permissions on $STORE_PATH" >&2
+ exit 1
+fi
+
+echo "Created keystore @ $STORE_PATH"
View
@@ -79,6 +79,12 @@ export EXE_CREATE_NEW_CERT
EXE_WRITE_SIGNING_POLICY="org.nimbustools.auto_common.ezpz_ca.SigningPolicy"
export EXE_WRITE_SIGNING_POLICY
+EXE_CREATE_CRL="org.nimbustools.auto_common.ezpz_ca.GenerateCRL"
+export EXE_CREATE_CRL
+
+EXE_KEYSTORE_FROM_PEM="org.nimbustools.auto_common.ezpz_ca.KeystoreFromPEM"
+export EXE_KEYSTORE_FROM_PEM
+
EXE_FIND_CA_PUBPEM="org.nimbustools.auto_common.ezpz_ca.FindCAPubFile"
EXE_FIND_CA_PRIVPEM="org.nimbustools.auto_common.ezpz_ca.FindCAPrivFile"
export EXE_FIND_CA_PUBPEM EXE_FIND_CA_PRIVPEM
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2009 University of Chicago
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package org.nimbustools.auto_common.ezpz_ca;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.FileReader;
+import java.security.cert.X509Certificate;
+import java.security.Security;
+
+import org.bouncycastle.openssl.PEMReader;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.globus.gsi.CertUtil;
+
+import javax.security.auth.x500.X500Principal;
+
+public class CertDN {
+
+
+ static {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public static String dnFromPath(String path) throws IOException {
+
+ final File certFile = new File(path);
+ if (!certFile.canRead()) {
+ final String msg = "File '" + path + "' can not be read.";
+ throw new IOException(msg);
+ }
+
+ final FileReader fr = new FileReader(certFile);
+ try {
+ final PEMReader reader =
+ new PEMReader(fr, null, BouncyCastleProvider.PROVIDER_NAME);
+ try {
+ final X509Certificate cert = (X509Certificate) reader.readObject();
+ final X500Principal principal = cert.getSubjectX500Principal();
+ final String DN = principal.getName(X500Principal.RFC2253);
+
+ return CertUtil.toGlobusID(DN, false);
+
+ } finally {
+ reader.close();
+ }
+ } finally {
+ fr.close();
+ }
+ }
+
+
+ public static void main(String[] args) {
+
+ if (args == null || args.length != 1) {
+ System.err.println("Needs these arguments:\n" +
+ "1 - the certificate file");
+ System.exit(1);
+ }
+
+ try {
+ final String dn = dnFromPath(args[0]);
+ System.out.println(dn);
+ } catch (Throwable t) {
+ System.err.println("Problem: " + t.getMessage());
+ t.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
@@ -34,7 +34,8 @@
public static final String certFooter = "-----END CERTIFICATE-----";
public static final String keyHeader = "-----BEGIN RSA PRIVATE KEY-----";
public static final String keyFooter = "-----END RSA PRIVATE KEY-----";
-
+ public static final String crlHeader = "-----BEGIN X509 CRL-----";
+ public static final String crlFooter = "-----END X509 CRL-----";
public void writeCert(X509Certificate cert,
KeyPair keyPair,
@@ -79,17 +80,23 @@ public void writeCert(X509Certificate cert,
* @return string
*/
public static String certToPEMString(String base64Data) {
- return toStringImpl(base64Data, false);
+ return toStringImpl(base64Data, false, false);
}
- private static String toStringImpl(String base64Data, boolean isKey) {
+ public static String crlToPEMString(String base64Data) {
+ return toStringImpl(base64Data, false, true);
+ }
+
+ private static String toStringImpl(String base64Data, boolean isKey, boolean isCRL) {
int length = LINE_LENGTH;
int offset = 0;
final StringBuffer buf = new StringBuffer(2048);
- if (isKey) {
+ if (isCRL) {
+ buf.append(crlHeader);
+ } else if (isKey) {
buf.append(keyHeader);
} else {
buf.append(certHeader);
@@ -106,7 +113,9 @@ private static String toStringImpl(String base64Data, boolean isKey) {
offset = offset + LINE_LENGTH;
}
- if (isKey) {
+ if (isCRL) {
+ buf.append(crlFooter);
+ } else if (isKey) {
buf.append(keyFooter);
} else {
buf.append(certFooter);
@@ -16,16 +16,22 @@
package org.nimbustools.auto_common.ezpz_ca;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.bouncycastle.asn1.x509.CRLNumber;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.globus.gsi.CertUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.X509V3CertificateGenerator;
+import org.bouncycastle.jce.X509V2CRLGenerator;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x509.X509Name;
import javax.security.auth.x500.X500Principal;
+import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
@@ -36,6 +42,8 @@
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.InvalidKeyException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateException;
@@ -56,6 +64,8 @@
private final X509Name caX509Name;
private final String targetString;
private final CertificateFactory factory;
+ private final X509V2CRLGenerator crlGen;
+
static {
Security.addProvider(new BouncyCastleProvider());
@@ -99,7 +109,7 @@ protected EzPzCA(X509Certificate caCert,
this.caPrivate = caPrivateKey;
this.caX509Name = new X509Principal(
- caX509.getIssuerX500Principal().getEncoded());
+ this.caX509.getIssuerX500Principal().getEncoded());
this.initializeGenerator();
@@ -113,6 +123,10 @@ protected EzPzCA(X509Certificate caCert,
"and Globus style DN = '" + globusCADN + "'. " +
"New DNs will look like this (RFC2253): '" +
this.targetString + "'";
+
+ this.crlGen = new X509V2CRLGenerator();
+ this.crlGen.setIssuerDN(this.caX509Name);
+ this.crlGen.setSignatureAlgorithm("SHA1withRSA");
}
public static String deriveSigningTargetString(X509Certificate caCert) throws CertificateException {
@@ -188,6 +202,30 @@ public X509Certificate signNewCertificate(String cnString,
return x509Cert;
}
+ public X509CRL generateCRL()
+ throws SignatureException, InvalidKeyException, NoSuchProviderException,
+ CertificateEncodingException {
+
+ this.crlGen.setThisUpdate(new Date());
+ final Calendar expires = Calendar.getInstance();
+ // this is fake, expiration does not matter
+ expires.add(Calendar.MONTH, GenerateNewCert.VALIDITY_MONTHS);
+ this.crlGen.setNextUpdate(expires.getTime());
+
+ // this is how you'd actually add an entry if we wanted one:
+ //this.crlGen.addCRLEntry(BigInteger.ONE, new Date(), CRLReason.PRIVILEGE_WITHDRAWN);
+
+ this.crlGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
+ new AuthorityKeyIdentifier(
+ new SubjectPublicKeyInfo(
+ new AlgorithmIdentifier("RSA"), this.caX509.getEncoded())));
+
+ this.crlGen.addExtension(X509Extensions.CRLNumber,
+ false, new CRLNumber(BigInteger.ONE));
+
+ return this.crlGen.generateX509CRL(this.caPrivate, "BC");
+ }
+
private String getTargetDN(String cnString) {
return getTargetDNfromSchema(this.targetString, "CN=" + cnString);
}
Oops, something went wrong.

0 comments on commit b86298e

Please sign in to comment.