1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23 package com.sun.org.apache.xml.internal.security.keys.content.x509; 24 25 import java.security.cert.X509Certificate; 26 import java.util.Arrays; 27 28 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; 29 import com.sun.org.apache.xml.internal.security.utils.Base64; 30 import com.sun.org.apache.xml.internal.security.utils.Constants; 31 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; 32 import org.w3c.dom.Document; 33 import org.w3c.dom.Element; 34 35 /** 36 * Handles SubjectKeyIdentifier (SKI) for X.509v3. 37 * 38 * @see <A HREF="http://java.sun.com/j2se/1.5.0/docs/api/java/security/cert/X509Extension.html"> 39 * Interface X509Extension</A> 40 */ 41 public class XMLX509SKI extends SignatureElementProxy implements XMLX509DataContent { 42 43 /** {@link org.apache.commons.logging} logging facility */ 44 private static java.util.logging.Logger log = 45 java.util.logging.Logger.getLogger(XMLX509SKI.class.getName()); 46 47 /** 48 * <CODE>SubjectKeyIdentifier (id-ce-subjectKeyIdentifier) (2.5.29.14)</CODE>: 49 * This extension identifies the public key being certified. It enables 50 * distinct keys used by the same subject to be differentiated 51 * (e.g., as key updating occurs). 52 * <BR /> 53 * A key identifier shall be unique with respect to all key identifiers 54 * for the subject with which it is used. This extension is always non-critical. 55 */ 56 public static final String SKI_OID = "2.5.29.14"; 57 58 /** 59 * Constructor X509SKI 60 * 61 * @param doc 62 * @param skiBytes 63 */ 64 public XMLX509SKI(Document doc, byte[] skiBytes) { 65 super(doc); 66 this.addBase64Text(skiBytes); 67 } 68 69 /** 70 * Constructor XMLX509SKI 71 * 72 * @param doc 73 * @param x509certificate 74 * @throws XMLSecurityException 75 */ 76 public XMLX509SKI(Document doc, X509Certificate x509certificate) 77 throws XMLSecurityException { 78 super(doc); 79 this.addBase64Text(XMLX509SKI.getSKIBytesFromCert(x509certificate)); 80 } 81 82 /** 83 * Constructor XMLX509SKI 84 * 85 * @param element 86 * @param BaseURI 87 * @throws XMLSecurityException 88 */ 89 public XMLX509SKI(Element element, String BaseURI) throws XMLSecurityException { 90 super(element, BaseURI); 91 } 92 93 /** 94 * Method getSKIBytes 95 * 96 * @return the skibytes 97 * @throws XMLSecurityException 98 */ 99 public byte[] getSKIBytes() throws XMLSecurityException { 100 return this.getBytesFromTextChild(); 101 } 102 103 /** 104 * Method getSKIBytesFromCert 105 * 106 * @param cert 107 * @return ski bytes from the given certificate 108 * 109 * @throws XMLSecurityException 110 * @see java.security.cert.X509Extension#getExtensionValue(java.lang.String) 111 */ 112 public static byte[] getSKIBytesFromCert(X509Certificate cert) 113 throws XMLSecurityException { 114 115 if (cert.getVersion() < 3) { 116 Object exArgs[] = { Integer.valueOf(cert.getVersion()) }; 117 throw new XMLSecurityException("certificate.noSki.lowVersion", exArgs); 118 } 119 120 /* 121 * Gets the DER-encoded OCTET string for the extension value 122 * (extnValue) identified by the passed-in oid String. The oid 123 * string is represented by a set of positive whole numbers 124 * separated by periods. 125 */ 126 byte[] extensionValue = cert.getExtensionValue(XMLX509SKI.SKI_OID); 127 if (extensionValue == null) { 128 throw new XMLSecurityException("certificate.noSki.null"); 129 } 130 131 /** 132 * Strip away first four bytes from the extensionValue 133 * The first two bytes are the tag and length of the extensionValue 134 * OCTET STRING, and the next two bytes are the tag and length of 135 * the ski OCTET STRING. 136 */ 137 byte skidValue[] = new byte[extensionValue.length - 4]; 138 139 System.arraycopy(extensionValue, 4, skidValue, 0, skidValue.length); 140 141 if (log.isLoggable(java.util.logging.Level.FINE)) { 142 log.log(java.util.logging.Level.FINE, "Base64 of SKI is " + Base64.encode(skidValue)); 143 } 144 145 return skidValue; 146 } 147 148 /** @inheritDoc */ 149 public boolean equals(Object obj) { 150 if (!(obj instanceof XMLX509SKI)) { 151 return false; 152 } 153 154 XMLX509SKI other = (XMLX509SKI) obj; 155 156 try { 157 return Arrays.equals(other.getSKIBytes(), this.getSKIBytes()); 158 } catch (XMLSecurityException ex) { 159 return false; 160 } 161 } 162 163 public int hashCode() { 164 int result = 17; 165 try { 166 byte[] bytes = getSKIBytes(); 167 for (int i = 0; i < bytes.length; i++) { 168 result = 31 * result + bytes[i]; 169 } 170 } catch (XMLSecurityException e) { 171 if (log.isLoggable(java.util.logging.Level.FINE)) { 172 log.log(java.util.logging.Level.FINE, e.getMessage(), e); 173 } 174 } 175 return result; 176 177 } 178 179 /** @inheritDoc */ 180 public String getBaseLocalName() { 181 return Constants._TAG_X509SKI; 182 } 183 }