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