001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.util.jce; 019 020 import java.io.ByteArrayInputStream; 021 import java.io.ByteArrayOutputStream; 022 import java.math.BigInteger; 023 import java.security.InvalidKeyException; 024 import java.security.NoSuchAlgorithmException; 025 import java.security.NoSuchProviderException; 026 import java.security.PrivateKey; 027 import java.security.PublicKey; 028 import java.security.SecureRandom; 029 import java.security.Signature; 030 import java.security.SignatureException; 031 import java.security.cert.X509Certificate; 032 import java.util.Date; 033 import java.util.Hashtable; 034 035 import org.apache.geronimo.util.asn1.ASN1EncodableVector; 036 import org.apache.geronimo.util.asn1.ASN1InputStream; 037 import org.apache.geronimo.util.asn1.ASN1Sequence; 038 import org.apache.geronimo.util.asn1.DERBitString; 039 import org.apache.geronimo.util.asn1.DERInteger; 040 import org.apache.geronimo.util.asn1.DERNull; 041 import org.apache.geronimo.util.asn1.DERObjectIdentifier; 042 import org.apache.geronimo.util.asn1.DEROutputStream; 043 import org.apache.geronimo.util.asn1.DERSequence; 044 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier; 045 import org.apache.geronimo.util.asn1.x509.SubjectPublicKeyInfo; 046 import org.apache.geronimo.util.asn1.x509.TBSCertificateStructure; 047 import org.apache.geronimo.util.asn1.x509.Time; 048 import org.apache.geronimo.util.asn1.x509.V1TBSCertificateGenerator; 049 import org.apache.geronimo.util.asn1.x509.X509CertificateStructure; 050 import org.apache.geronimo.util.asn1.x509.X509Name; 051 import org.apache.geronimo.util.jce.provider.X509CertificateObject; 052 053 /** 054 * class to produce an X.509 Version 1 certificate. 055 * 056 * @deprecated use the equivalent class in org.apache.geronimo.util.x509 057 */ 058 public class X509V1CertificateGenerator 059 { 060 private V1TBSCertificateGenerator tbsGen; 061 private DERObjectIdentifier sigOID; 062 private AlgorithmIdentifier sigAlgId; 063 private String signatureAlgorithm; 064 065 private static Hashtable algorithms = new Hashtable(); 066 067 static 068 { 069 algorithms.put("MD2WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.2")); 070 algorithms.put("MD2WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.2")); 071 algorithms.put("MD5WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.4")); 072 algorithms.put("MD5WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.4")); 073 algorithms.put("SHA1WITHRSAENCRYPTION", new DERObjectIdentifier("1.2.840.113549.1.1.5")); 074 algorithms.put("SHA1WITHRSA", new DERObjectIdentifier("1.2.840.113549.1.1.5")); 075 algorithms.put("RIPEMD160WITHRSAENCRYPTION", new DERObjectIdentifier("1.3.36.3.3.1.2")); 076 algorithms.put("RIPEMD160WITHRSA", new DERObjectIdentifier("1.3.36.3.3.1.2")); 077 algorithms.put("SHA1WITHDSA", new DERObjectIdentifier("1.2.840.10040.4.3")); 078 algorithms.put("DSAWITHSHA1", new DERObjectIdentifier("1.2.840.10040.4.3")); 079 algorithms.put("SHA1WITHECDSA", new DERObjectIdentifier("1.2.840.10045.4.1")); 080 algorithms.put("ECDSAWITHSHA1", new DERObjectIdentifier("1.2.840.10045.4.1")); 081 } 082 083 public X509V1CertificateGenerator() 084 { 085 tbsGen = new V1TBSCertificateGenerator(); 086 } 087 088 /** 089 * reset the generator 090 */ 091 public void reset() 092 { 093 tbsGen = new V1TBSCertificateGenerator(); 094 } 095 096 /** 097 * set the serial number for the certificate. 098 */ 099 public void setSerialNumber( 100 BigInteger serialNumber) 101 { 102 tbsGen.setSerialNumber(new DERInteger(serialNumber)); 103 } 104 105 /** 106 * Set the issuer distinguished name - the issuer is the entity whose private key is used to sign the 107 * certificate. 108 */ 109 public void setIssuerDN( 110 X509Name issuer) 111 { 112 tbsGen.setIssuer(issuer); 113 } 114 115 public void setNotBefore( 116 Date date) 117 { 118 tbsGen.setStartDate(new Time(date)); 119 } 120 121 public void setNotAfter( 122 Date date) 123 { 124 tbsGen.setEndDate(new Time(date)); 125 } 126 127 /** 128 * Set the subject distinguished name. The subject describes the entity associated with the public key. 129 */ 130 public void setSubjectDN( 131 X509Name subject) 132 { 133 tbsGen.setSubject(subject); 134 } 135 136 public void setPublicKey( 137 PublicKey key) 138 { 139 try 140 { 141 tbsGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream( 142 new ByteArrayInputStream(key.getEncoded())).readObject())); 143 } 144 catch (Exception e) 145 { 146 throw new IllegalArgumentException("unable to process key - " + e.getMessage(), e); 147 } 148 } 149 150 public void setSignatureAlgorithm( 151 String signatureAlgorithm) 152 { 153 this.signatureAlgorithm = signatureAlgorithm; 154 155 sigOID = (DERObjectIdentifier)algorithms.get(signatureAlgorithm.toUpperCase()); 156 157 if (sigOID == null) 158 { 159 throw new IllegalArgumentException("Unknown signature type requested"); 160 } 161 162 sigAlgId = new AlgorithmIdentifier(this.sigOID, new DERNull()); 163 164 tbsGen.setSignature(sigAlgId); 165 } 166 167 /** 168 * generate an X509 certificate, based on the current issuer and subject 169 * using the default provider "BC". 170 */ 171 public X509Certificate generateX509Certificate( 172 PrivateKey key) 173 throws SecurityException, SignatureException, InvalidKeyException 174 { 175 try 176 { 177 return generateX509Certificate(key, null, null); 178 } 179 catch (NoSuchProviderException e) 180 { 181 throw (SecurityException)new SecurityException("JCE provider not installed!").initCause(e); 182 } 183 } 184 185 /** 186 * generate an X509 certificate, based on the current issuer and subject 187 * using the default provider and the passed in source of randomness 188 */ 189 public X509Certificate generateX509Certificate( 190 PrivateKey key, 191 SecureRandom random) 192 throws SecurityException, SignatureException, InvalidKeyException 193 { 194 try 195 { 196 return generateX509Certificate(key, null, random); 197 } 198 catch (NoSuchProviderException e) 199 { 200 throw (SecurityException)new SecurityException("JCE provider not installed!").initCause(e); 201 } 202 } 203 204 /** 205 * generate an X509 certificate, based on the current issuer and subject, 206 * using the passed in provider for the signing, and the passed in source 207 * of randomness (if required). 208 */ 209 public X509Certificate generateX509Certificate( 210 PrivateKey key, 211 String provider) 212 throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException 213 { 214 return generateX509Certificate(key, provider, null); 215 } 216 217 /** 218 * generate an X509 certificate, based on the current issuer and subject, 219 * using the passed in provider for the signing, and the passed in source 220 * of randomness (if required). 221 */ 222 public X509Certificate generateX509Certificate( 223 PrivateKey key, 224 String provider, 225 SecureRandom random) 226 throws NoSuchProviderException, SecurityException, SignatureException, InvalidKeyException 227 { 228 Signature sig = null; 229 230 try 231 { 232 if (provider == null) { 233 sig = Signature.getInstance(sigOID.getId()); 234 } 235 else { 236 sig = Signature.getInstance(sigOID.getId(), provider); 237 } 238 } 239 catch (NoSuchAlgorithmException ex) 240 { 241 try 242 { 243 if (provider == null) { 244 sig = Signature.getInstance(signatureAlgorithm); 245 } 246 else { 247 sig = Signature.getInstance(signatureAlgorithm, provider); 248 } 249 } 250 catch (NoSuchAlgorithmException e) 251 { 252 throw (SecurityException)new SecurityException("exception creating signature: " + e.getMessage()).initCause(e); 253 } 254 } 255 256 if (random != null) 257 { 258 sig.initSign(key, random); 259 } 260 else 261 { 262 sig.initSign(key); 263 } 264 265 TBSCertificateStructure tbsCert = tbsGen.generateTBSCertificate(); 266 267 try 268 { 269 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 270 DEROutputStream dOut = new DEROutputStream(bOut); 271 272 dOut.writeObject(tbsCert); 273 274 sig.update(bOut.toByteArray()); 275 } 276 catch (Exception e) 277 { 278 throw (SecurityException)new SecurityException("exception encoding TBS cert - " + e.getMessage()).initCause(e); 279 } 280 281 ASN1EncodableVector v = new ASN1EncodableVector(); 282 283 v.add(tbsCert); 284 v.add(sigAlgId); 285 v.add(new DERBitString(sig.sign())); 286 287 return new X509CertificateObject(new X509CertificateStructure(new DERSequence(v))); 288 } 289 }