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.provider; 020 021 import java.io.ByteArrayOutputStream; 022 import java.io.IOException; 023 import java.math.BigInteger; 024 import java.security.interfaces.RSAPrivateCrtKey; 025 import java.security.spec.RSAPrivateCrtKeySpec; 026 027 import org.apache.geronimo.util.asn1.ASN1Sequence; 028 import org.apache.geronimo.util.asn1.DERNull; 029 import org.apache.geronimo.util.asn1.DEROutputStream; 030 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers; 031 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo; 032 import org.apache.geronimo.util.asn1.pkcs.RSAPrivateKeyStructure; 033 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier; 034 import org.apache.geronimo.util.crypto.params.RSAPrivateCrtKeyParameters; 035 036 /** 037 * A provider representation for a RSA private key, with CRT factors included. 038 */ 039 public class JCERSAPrivateCrtKey 040 extends JCERSAPrivateKey 041 implements RSAPrivateCrtKey 042 { 043 private BigInteger publicExponent; 044 private BigInteger primeP; 045 private BigInteger primeQ; 046 private BigInteger primeExponentP; 047 private BigInteger primeExponentQ; 048 private BigInteger crtCoefficient; 049 050 /** 051 * construct a private key from it's org.apache.geronimo.util.crypto equivalent. 052 * 053 * @param key the parameters object representing the private key. 054 */ 055 JCERSAPrivateCrtKey( 056 RSAPrivateCrtKeyParameters key) 057 { 058 super(key); 059 060 this.publicExponent = key.getPublicExponent(); 061 this.primeP = key.getP(); 062 this.primeQ = key.getQ(); 063 this.primeExponentP = key.getDP(); 064 this.primeExponentQ = key.getDQ(); 065 this.crtCoefficient = key.getQInv(); 066 } 067 068 /** 069 * construct a private key from an RSAPrivateCrtKeySpec 070 * 071 * @param spec the spec to be used in construction. 072 */ 073 JCERSAPrivateCrtKey( 074 RSAPrivateCrtKeySpec spec) 075 { 076 this.modulus = spec.getModulus(); 077 this.publicExponent = spec.getPublicExponent(); 078 this.privateExponent = spec.getPrivateExponent(); 079 this.primeP = spec.getPrimeP(); 080 this.primeQ = spec.getPrimeQ(); 081 this.primeExponentP = spec.getPrimeExponentP(); 082 this.primeExponentQ = spec.getPrimeExponentQ(); 083 this.crtCoefficient = spec.getCrtCoefficient(); 084 } 085 086 /** 087 * construct a private key from another RSAPrivateCrtKey. 088 * 089 * @param key the object implementing the RSAPrivateCrtKey interface. 090 */ 091 JCERSAPrivateCrtKey( 092 RSAPrivateCrtKey key) 093 { 094 this.modulus = key.getModulus(); 095 this.publicExponent = key.getPublicExponent(); 096 this.privateExponent = key.getPrivateExponent(); 097 this.primeP = key.getPrimeP(); 098 this.primeQ = key.getPrimeQ(); 099 this.primeExponentP = key.getPrimeExponentP(); 100 this.primeExponentQ = key.getPrimeExponentQ(); 101 this.crtCoefficient = key.getCrtCoefficient(); 102 } 103 104 /** 105 * construct an RSA key from a private key info object. 106 */ 107 JCERSAPrivateCrtKey( 108 PrivateKeyInfo info) 109 { 110 this(new RSAPrivateKeyStructure((ASN1Sequence)info.getPrivateKey())); 111 } 112 113 /** 114 * construct an RSA key from a ASN.1 RSA private key object. 115 */ 116 JCERSAPrivateCrtKey( 117 RSAPrivateKeyStructure key) 118 { 119 this.modulus = key.getModulus(); 120 this.publicExponent = key.getPublicExponent(); 121 this.privateExponent = key.getPrivateExponent(); 122 this.primeP = key.getPrime1(); 123 this.primeQ = key.getPrime2(); 124 this.primeExponentP = key.getExponent1(); 125 this.primeExponentQ = key.getExponent2(); 126 this.crtCoefficient = key.getCoefficient(); 127 } 128 129 /** 130 * return the encoding format we produce in getEncoded(). 131 * 132 * @return the encoding format we produce in getEncoded(). 133 */ 134 public String getFormat() 135 { 136 return "PKCS#8"; 137 } 138 139 /** 140 * Return a PKCS8 representation of the key. The sequence returned 141 * represents a full PrivateKeyInfo object. 142 * 143 * @return a PKCS8 representation of the key. 144 */ 145 public byte[] getEncoded() 146 { 147 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 148 DEROutputStream dOut = new DEROutputStream(bOut); 149 PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPrivateKeyStructure(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()).getDERObject()); 150 151 try 152 { 153 dOut.writeObject(info); 154 dOut.close(); 155 } 156 catch (IOException e) 157 { 158 throw new RuntimeException("Error encoding RSA public key"); 159 } 160 161 return bOut.toByteArray(); 162 } 163 164 /** 165 * return the public exponent. 166 * 167 * @return the public exponent. 168 */ 169 public BigInteger getPublicExponent() 170 { 171 return publicExponent; 172 } 173 174 /** 175 * return the prime P. 176 * 177 * @return the prime P. 178 */ 179 public BigInteger getPrimeP() 180 { 181 return primeP; 182 } 183 184 /** 185 * return the prime Q. 186 * 187 * @return the prime Q. 188 */ 189 public BigInteger getPrimeQ() 190 { 191 return primeQ; 192 } 193 194 /** 195 * return the prime exponent for P. 196 * 197 * @return the prime exponent for P. 198 */ 199 public BigInteger getPrimeExponentP() 200 { 201 return primeExponentP; 202 } 203 204 /** 205 * return the prime exponent for Q. 206 * 207 * @return the prime exponent for Q. 208 */ 209 public BigInteger getPrimeExponentQ() 210 { 211 return primeExponentQ; 212 } 213 214 /** 215 * return the CRT coefficient. 216 * 217 * @return the CRT coefficient. 218 */ 219 public BigInteger getCrtCoefficient() 220 { 221 return crtCoefficient; 222 } 223 224 public boolean equals(Object o) 225 { 226 if ( !(o instanceof RSAPrivateCrtKey) ) 227 { 228 return false; 229 } 230 231 if ( o == this ) 232 { 233 return true; 234 } 235 236 RSAPrivateCrtKey key = (RSAPrivateCrtKey)o; 237 238 return this.getModulus().equals(key.getModulus()) 239 && this.getPublicExponent().equals(key.getPublicExponent()) 240 && this.getPrivateExponent().equals(key.getPrivateExponent()) 241 && this.getPrimeP().equals(key.getPrimeP()) 242 && this.getPrimeQ().equals(key.getPrimeQ()) 243 && this.getPrimeExponentP().equals(key.getPrimeExponentP()) 244 && this.getPrimeExponentQ().equals(key.getPrimeExponentQ()) 245 && this.getCrtCoefficient().equals(key.getCrtCoefficient()); 246 } 247 248 public String toString() 249 { 250 StringBuffer buf = new StringBuffer(); 251 String nl = System.getProperty("line.separator"); 252 253 buf.append("RSA Private CRT Key" + nl); 254 buf.append(" modulus: " + this.getModulus().toString(16) + nl); 255 buf.append(" public exponent: " + this.getPublicExponent().toString(16) + nl); 256 buf.append(" private exponent: " + this.getPrivateExponent().toString(16) + nl); 257 buf.append(" primeP: " + this.getPrimeP().toString(16) + nl); 258 buf.append(" primeQ: " + this.getPrimeQ().toString(16) + nl); 259 buf.append(" primeExponentP: " + this.getPrimeExponentP().toString(16) + nl); 260 buf.append(" primeExponentQ: " + this.getPrimeExponentQ().toString(16) + nl); 261 buf.append(" crtCoefficient: " + this.getCrtCoefficient().toString(16) + nl); 262 263 return buf.toString(); 264 } 265 }