Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
Merge pull request #3 from vmware/certificates
Browse files Browse the repository at this point in the history
Certificate Support
  • Loading branch information
dlinsley authored Oct 1, 2017
2 parents 530bf41 + 47eeb78 commit d7ae7a2
Show file tree
Hide file tree
Showing 21 changed files with 1,151 additions and 109 deletions.
Binary file modified crypto_api_explorer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
/*
* Copyright (c) 2017 VMware, Inc. All Rights Reserved.
* SPDX-License-Identifier: BSD-2-Clause
*/
package com.vmware.o11n.plugin.crypto.model;

import java.io.IOException;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.naming.InvalidNameException;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.vmware.o11n.plugin.crypto.service.CryptoCertificateService;
import com.vmware.o11n.plugin.sdk.annotation.VsoConstructor;
import com.vmware.o11n.plugin.sdk.annotation.VsoMethod;
import com.vmware.o11n.plugin.sdk.annotation.VsoObject;
import com.vmware.o11n.plugin.sdk.annotation.VsoParam;
import com.vmware.o11n.plugin.sdk.annotation.VsoProperty;


@VsoObject(
create=true,
strict=true,
description="A scripting object representing a X.509 certificate")
public class CryptoCertificate implements Serializable, Cloneable {

@Autowired
private static CryptoCertificateService service;

private final Logger log = LoggerFactory.getLogger(CryptoCertificate.class);

/* Constants */
private static final long serialVersionUID = 7252197349636955057L;
public static final String TYPE = "CryptoCertificate";
private static final String[] EMPTY_STRING_ARRAY = new String[0];

/* Local write once variables: */
private final X509Certificate cert;
private final String certString; //PEM encoded certificate


@VsoConstructor(description="A X.509 Certificate Object")
public CryptoCertificate(@VsoParam(description="PEM encoded certificate") String certString) {
if (service == null) {
service = new CryptoCertificateService();
}
try {
this.cert = service.parseCertificate(certString);
this.certString = CryptoUtil.pemEncode(this.cert);
} catch (CertificateException ce) {
throw new IllegalArgumentException("Invalid certificate");
}
}

public CryptoCertificate(X509Certificate cert) throws CertificateEncodingException {
if (service == null) {
service = new CryptoCertificateService();
}
this.cert = cert;
this.certString = CryptoUtil.pemEncode(cert);
}



/**
*
* @return
*/
@VsoProperty(name="encodedBase64",
description="Encoded form of the certificate encoded as a Base64 string. Hashing this can create a fingerprint")
public String getEncodedBase64() {
String toReturn = null;
try {
toReturn = service.getEncodedBase64(this.cert);
} catch (CertificateException ce) {
log.error(ce.getMessage());
} catch (Throwable e) {
log.error("Unexpected exception: "+e.getMessage());
}
return toReturn;
}

/**
*
* @return
*/
@VsoProperty(name="issuedByDN",description="Distinguished Name the certificate was issued by")
public String getIssuedByDN() {
return this.cert.getIssuerDN().getName();
}

/**
*
* @return
* @throws InvalidNameException
*/
@VsoProperty(name="issuedByMap",description="issuedByDN parsed into key/value pairs")
public Map<String,String> getIssuedByMap() throws InvalidNameException {
return service.parseDN(this.getIssuedByDN());
}

/**
*
* @return
*/
@VsoProperty(name="issuedToDN",description="Distinguished Name the certificate was issued to")
public String getIssuedToDN() {
return this.cert.getSubjectDN().getName();
}

/**
*
* @return
* @throws InvalidNameException
*/
@VsoProperty(name="issuedToMap",description="issuedToDN parsed into key/value pairs")
public Map<String,String> getIssuedToMap() throws InvalidNameException {
return service.parseDN(this.getIssuedToDN());
}


/**
*
* @return
*/
@VsoProperty(name="pemEncoded",
description="PEM Encoding of the certificate")
public String getPemEncoded() {
return this.certString;
}

/**
*
* @return
*/
@VsoProperty(name="publicKeyPem",
description="The RSA Public Key in PEM format found in the certificate")
public String getPublicKeyPem() {
return service.getPublicKeyPem(this.cert);
}

/**
*
* @return
*/
@VsoProperty(name="serialNumber",description="Serial Number of the Certificate")
public String getSerialNumber() {
return service.getSerialNumber(this.cert);
}

/**
*
* @return
*/
@VsoProperty(name="sha1Fingerprint",
description="SHA1 fingerprint of the certificate")
public String getSha1Fingerprint() {
String toReturn = null;
try {
toReturn = service.getSha1Fingerprint(this.cert);
} catch (CertificateException ce) {
log.error(ce.getMessage());
} catch (Throwable e) {
log.error("Unexpected exception: "+e.getMessage());
}
return toReturn;
}

/**
*
* @return
*/
@VsoProperty(name="sha256Fingerprint",
description="SHA256 fingerprint of the certificate")
public String getSha256Fingerprint() {
String toReturn = null;
try {
toReturn = service.getSha256Fingerprint(this.cert);
} catch (CertificateException ce) {
log.error(ce.getMessage());
} catch (Throwable e) {
log.error("Unexpected exception: "+e.getMessage());
}
return toReturn;
}

/**
*
* @return
*/
@VsoProperty(name="signatureAlgorithm",description="Signature algorithm used by the certificate signer")
public String getSignatureAlgorithm() {
return this.cert.getSigAlgName();
}

/**
*
*
* @return
*/
@VsoProperty(name="signatureBase64",description="Base64 encoded signature of the certificate")
public String getSignatureBase64 () {
byte[] sig = this.cert.getSignature();
return Base64.encodeBase64String(sig);
}


/**
*
* @return
*/
@VsoProperty(name="subjectAlternativeNames",
description="A list of subject alternative names found in the certificate. Each will have a colon delimited prefix for the type of SAN found. ex: \"dns:\"")
public String[] getSubjectAlternativeNames() {
try {
List<String> san = service.getSubjectAlternativeNames(this.cert);
if (san != null && san.size() > 0) {
return san.toArray(EMPTY_STRING_ARRAY);
}
} catch (CertificateParsingException e) {
log.error(e.toString());
}
return EMPTY_STRING_ARRAY;
}

/**
*
* @return
*/
@VsoMethod(vsoReturnType="Date",
description="The certificate is valid before this date")
public Date getValidBefore() {
return this.cert.getNotAfter();
}

/**
*
* @return
*/
@VsoMethod(vsoReturnType="Date",
description="The certificate is valid after this date")
public Date getValidAfter() {
return this.cert.getNotBefore();
}

/**
*
* @param date
* @return
*/
@VsoMethod(vsoReturnType="boolean",
description="Is the certificate valid based on a provided date")
public boolean isValidOn( @VsoParam(vsoType="Date",description="Date to check certificate validity on") Date date) {
final Date validAfter = this.cert.getNotBefore();
final Date validBefore = this.cert.getNotAfter();

if (validAfter.compareTo(date) > 0) { //'validAfter' is after date
//certificate is not valid yet compared to this date
return false;
}
if (validBefore.compareTo(date) < 0) { // 'validBefore is before date'
//certificate is expired compared to this date
return false;
}
// passing both these checks, the cert is valid for this date
return true;
}

/**
*
* @param pemKey
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws IOException
*/
@VsoMethod(vsoReturnType="boolean",description="Verifies the Certificate was signed by a signing certificates private key")
public boolean verify( @VsoParam(description="PEM encoded PublicKey of the signing Certificate") String pemKey) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
return service.verifyCert(this.cert, pemKey);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2017 VMware, Inc. All Rights Reserved.
* SPDX-License-Identifier: BSD-2-Clause
*/
package com.vmware.o11n.plugin.crypto.model;

import java.io.IOException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.vmware.o11n.plugin.crypto.service.CryptoCertificateService;
import com.vmware.o11n.plugin.sdk.annotation.VsoMethod;
import com.vmware.o11n.plugin.sdk.annotation.VsoObject;
import com.vmware.o11n.plugin.sdk.annotation.VsoParam;
import com.vmware.o11n.plugin.sdk.spring.AbstractSpringPluginFactory;

import ch.dunes.vso.sdk.api.IPluginFactory;

@VsoObject(
create=false,
strict=true,
singleton=true,
description="Provides methods to parse or fetch certificates")
public class CryptoCertificateManager {
private final Logger log = LoggerFactory.getLogger(CryptoCertificateManager.class);

@Autowired
private CryptoCertificateService service;

public static CryptoCertificateManager createScriptingSingleton(IPluginFactory factory) {
return ((AbstractSpringPluginFactory) factory).createScriptingObject(CryptoCertificateManager.class);
}

@VsoMethod(description="parses a PEM encoded X.509 Certificate")
public CryptoCertificate parseCertificatePem(
@VsoParam(description="PEM encoded Certificate")String pemCertString) throws CertificateException {
X509Certificate cert = service.parseCertificate(pemCertString);
return new CryptoCertificate(cert);
}

@VsoMethod(description="Returns array of certificates presented by an https server")
public CryptoCertificate[] getHttpsCertificate(
@VsoParam(description="HTTPS URL to get certificate chain of") String urlString) throws KeyManagementException, NoSuchAlgorithmException, IOException, CertificateEncodingException {
ArrayList<CryptoCertificate> toReturn = new ArrayList<>();
URL url = new URL(urlString);
List<X509Certificate> certs = service.getCertHttps(url);
if (log.isDebugEnabled() && certs != null){
log.debug("Number of certs found at url: "+certs.size());
}
for (X509Certificate cert : certs) {
toReturn.add(new CryptoCertificate(cert));
}
return toReturn.toArray(new CryptoCertificate[toReturn.size()]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
*/
package com.vmware.o11n.plugin.crypto.model;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.vmware.o11n.plugin.crypto.service.CryptoDigestService;
import com.vmware.o11n.plugin.sdk.annotation.VsoMethod;
import com.vmware.o11n.plugin.sdk.annotation.VsoObject;
import com.vmware.o11n.plugin.sdk.annotation.VsoParam;
Expand All @@ -21,6 +24,7 @@

public class CryptoDigest {
public static final String TYPE = "CryptoDigest";
private final Logger log = LoggerFactory.getLogger(CryptoDigest.class);

@Autowired
private CryptoDigestService service;
Expand Down
Loading

0 comments on commit d7ae7a2

Please sign in to comment.