org.opensaml.xml.security.x509.X509Util Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xmltooling Show documentation
Show all versions of xmltooling Show documentation
XMLTooling-J is a low-level library that may be used to construct libraries that allow developers to work with XML in a Java beans manner.
The newest version!
/*
* Licensed to the University Corporation for Advanced Internet Development,
* Inc. (UCAID) under one or more contributor license agreements. See the
* NOTICE file distributed with this work for additional information regarding
* copyright ownership. The UCAID licenses this file to You 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.opensaml.xml.security.x509;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CRLException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import javax.security.auth.x500.X500Principal;
import org.apache.commons.ssl.TrustMaterial;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
import org.bouncycastle.x509.extension.X509ExtensionUtil;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.SecurityHelper;
import org.opensaml.xml.util.DatatypeHelper;
import org.opensaml.xml.util.IPAddressHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utility class for working with X509 objects.
*/
public class X509Util {
/** Encoding used to store a key or certificate in a file. */
public static enum ENCODING_FORMAT {
PEM, DER
};
/** Common Name (CN) OID. */
public static final String CN_OID = "2.5.4.3";
/** RFC 2459 Other Subject Alt Name type. */
public static final Integer OTHER_ALT_NAME = new Integer(0);
/** RFC 2459 RFC 822 (email address) Subject Alt Name type. */
public static final Integer RFC822_ALT_NAME = new Integer(1);
/** RFC 2459 DNS Subject Alt Name type. */
public static final Integer DNS_ALT_NAME = new Integer(2);
/** RFC 2459 X.400 Address Subject Alt Name type. */
public static final Integer X400ADDRESS_ALT_NAME = new Integer(3);
/** RFC 2459 Directory Name Subject Alt Name type. */
public static final Integer DIRECTORY_ALT_NAME = new Integer(4);
/** RFC 2459 EDI Party Name Subject Alt Name type. */
public static final Integer EDI_PARTY_ALT_NAME = new Integer(5);
/** RFC 2459 URI Subject Alt Name type. */
public static final Integer URI_ALT_NAME = new Integer(6);
/** RFC 2459 IP Address Subject Alt Name type. */
public static final Integer IP_ADDRESS_ALT_NAME = new Integer(7);
/** RFC 2459 Registered ID Subject Alt Name type. */
public static final Integer REGISTERED_ID_ALT_NAME = new Integer(8);
/** Constructed. */
protected X509Util() {
}
/**
* Determines the certificate, from the collection, associated with the private key.
*
* @param certs certificates to check
* @param privateKey entity's private key
*
* @return the certificate associated with entity's private key or null if not certificate in the collection is
* associated with the given private key
*
* @throws SecurityException thrown if the public or private keys checked are of an unsupported type
*
* @since 1.2
*/
public static X509Certificate determineEntityCertificate(Collection certs, PrivateKey privateKey)
throws SecurityException {
if (certs == null || privateKey == null) {
return null;
}
for (X509Certificate certificate : certs) {
try {
if (SecurityHelper.matchKeyPair(certificate.getPublicKey(), privateKey)) {
return certificate;
}
} catch (SecurityException e) {
// An exception here is just a false match.
// Java 7 apparently throws in this case.
}
}
return null;
}
/**
* Gets the commons names that appear within the given distinguished name. The returned list provides the names in
* the order they appeared in the DN.
*
* @param dn the DN to extract the common names from
*
* @return the common names that appear in the DN in the order they appear or null if the given DN is null
*/
public static List getCommonNames(X500Principal dn) {
Logger log = getLogger();
if (dn == null) {
return null;
}
log.debug("Extracting CNs from the following DN: {}", dn.toString());
List commonNames = new LinkedList();
try {
ASN1InputStream asn1Stream = new ASN1InputStream(dn.getEncoded());
ASN1Primitive parent = asn1Stream.readObject();
String cn = null;
ASN1Primitive dnComponent;
ASN1Sequence grandChild;
ASN1ObjectIdentifier componentId;
for (int i = 0; i < ((ASN1Sequence) parent).size(); i++) {
dnComponent = ((ASN1Sequence) parent).getObjectAt(i).toASN1Primitive();
if (!(dnComponent instanceof ASN1Set)) {
log.debug("No DN components.");
continue;
}
// Each DN component is a set
for (int j = 0; j < ((ASN1Set) dnComponent).size(); j++) {
grandChild = (ASN1Sequence) ((ASN1Set) dnComponent).getObjectAt(j).toASN1Primitive();
if (grandChild.getObjectAt(0) != null
&& grandChild.getObjectAt(0).toASN1Primitive() instanceof ASN1ObjectIdentifier) {
componentId = (ASN1ObjectIdentifier) grandChild.getObjectAt(0).toASN1Primitive();
if (CN_OID.equals(componentId.getId())) {
// OK, this dn component is actually a cn attribute
if (grandChild.getObjectAt(1) != null
&& grandChild.getObjectAt(1).toASN1Primitive() instanceof ASN1String) {
cn = ((ASN1String) grandChild.getObjectAt(1).toASN1Primitive()).getString();
commonNames.add(cn);
}
}
}
}
}
asn1Stream.close();
return commonNames;
} catch (IOException e) {
log.error("Unable to extract common names from DN: ASN.1 parsing failed: " + e);
return null;
}
}
/**
* Gets the list of alternative names of a given name type.
*
* @param certificate the certificate to extract the alternative names from
* @param nameTypes the name types
*
* @return the alt names, of the given type, within the cert
*/
public static List getAltNames(X509Certificate certificate, Integer[] nameTypes) {
Logger log = getLogger();
if (certificate == null) {
return null;
}
List