/* * Copyright (c) 2011-2012 ICM Uniwersytet Warszawski All rights reserved. * See LICENCE file for licensing information. * * Derived from the code copyrighted and licensed as follows: * * Copyright (c) Members of the EGEE Collaboration. 2004. * See http://www.eu-egee.org/partners/ for details on the copyright * holders. * * 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 eu.emi.security.authn.x509.helpers.proxy; import java.io.IOException; import java.security.cert.X509Certificate; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import eu.emi.security.authn.x509.helpers.CertificateHelpers; /** * A class for generating and parsing the proxy tracing extensions. <br> * See <a href="http://www.eugridpma.org/documentation/OIDProxyDelegationTracing.pdf"> OIDProxyDelegationTracing * documentation. </a> <br> * The proxy tracing extension format is below. It is used to trace the proxy delegation chain by putting in each proxy * the url of the service accepting the delegation and the url of the client initiating it. Often the delegation is from * service to service, in which case it is easy to use the url of the service. If the initiator of the delegation is a * user, then the client should put an url containing the client program as the scheme, the host name or IP address and * possibly the username as the path. <br> * At the moment only the URI is supported. * * <pre> * iGTFProxyTracingIssuerName ::= GeneralNames * iGTFProxyTracingSubjectName ::= GeneralNames * * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName * * GeneralName ::= CHOICE { * otherName [0] OtherName, * rfc822Name [1] IA5String, * dNSName [2] IA5String, * x400Address [3] ORAddress, * directoryName [4] Name, * ediPartyName [5] EDIPartyName, * uniformResourceIdentifier [6] IA5String, * iPAddress [7] OCTET STRING, * registeredID [8] OBJECT IDENTIFIER} * * OtherName ::= SEQUENCE { * type-id OBJECT IDENTIFIER, * value [0] EXPLICIT ANY DEFINED BY type-id } * * EDIPartyName ::= SEQUENCE { * nameAssigner [0] DirectoryString OPTIONAL, * partyName [1] DirectoryString } * * DirectoryString ::= CHOICE { * teletexString TeletexString (SIZE (1..maxSize), * printableString PrintableString (SIZE (1..maxSize)), * universalString UniversalString (SIZE (1..maxSize)), * bmpString BMPString (SIZE(1..maxSIZE)) * } * </pre> * * @author joni.hahkala@cern.ch * @author K. Benedyczak */ public class ProxyTracingExtension extends ASN1Object { /** The OID to identify issuer proxy tracing extension. */ public static final String PROXY_TRACING_ISSUER_EXTENSION_OID = "1.2.840.113612.5.5.1.1.1.1"; /** The OID to identify subject proxy tracing extension. */ public static final String PROXY_TRACING_SUBJECT_EXTENSION_OID = "1.2.840.113612.5.5.1.1.1.2"; /** The OID to identify issuer proxy tracing type. */ public static final int ISSUER_EXTENSION = 1; /** The OID to identify issuer proxy tracing type. */ public static final int SUBJECT_EXTENSION = 2; /** * The tracing generalNames object that wraps the generalName. */ private GeneralNames names = null; /** * The tracing generalName object. */ private GeneralName name = null; /** * Generates a new proxy tracing item from the URL. * * @param url * The URL to identify the issuer or the subject. */ public ProxyTracingExtension(String url) { name = new GeneralName(GeneralName.uniformResourceIdentifier, url); names = new GeneralNames(name); } /** * Parses the information in the byte array (GeneralNames ASN1 sequence * of GeneralName) into a proxy tracing extension object. * * @param bytes * The bytes of ASN1 encoded proxy tracing extension. * @throws IOException * In case the byte array does not contain a valid ASN1 * encoded proxy tracing extension. */ public ProxyTracingExtension(byte[] bytes) throws IOException { names = GeneralNames.getInstance(ASN1Primitive.fromByteArray(bytes)); name = names.getNames()[0]; } /** * Returns the URL of the proxy tracing issuer if present. * * @param cert certificate * @param issuer issuer * @return The proxy tracing issuer URL in String format, or null if no * extension was found or it was empty. * @throws IOException * Thrown in case the parsing of the information failed. */ public static ProxyTracingExtension getInstance(X509Certificate cert, boolean issuer) throws IOException { byte[] bytes = CertificateHelpers.getExtensionBytes(cert, issuer ? ProxyTracingExtension.PROXY_TRACING_ISSUER_EXTENSION_OID : ProxyTracingExtension.PROXY_TRACING_SUBJECT_EXTENSION_OID); if (bytes == null || bytes.length == 0) return null; return new ProxyTracingExtension(bytes); } /** * Returns the URL inside the proxy tracing data structure. * * @return The URL in String format. */ public String getURL() { if (name.getTagNo() != GeneralName.uniformResourceIdentifier) return null; DERIA5String ia5String = (DERIA5String) name.getName(); return ia5String.getString(); } /** * Returns the general names structure that holds the trace information. * * @return The generalNames object that has the trace information. */ public GeneralNames getNames() { return names; } /** * {@inheritDoc} */ @Override public ASN1Primitive toASN1Primitive() { return names.toASN1Primitive(); } }