1 /** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one or more 4 * contributor license agreements. See the NOTICE file distributed with 5 * this work for additional information regarding copyright ownership. 6 * The ASF licenses this file to You under the Apache License, Version 2.0 7 * (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.geronimo.util.jce.provider; 20 21 import java.io.ByteArrayOutputStream; 22 import java.io.IOException; 23 import java.io.ObjectInputStream; 24 import java.io.ObjectOutputStream; 25 import java.math.BigInteger; 26 import java.util.Enumeration; 27 import java.util.Hashtable; 28 import java.util.Vector; 29 30 import javax.crypto.interfaces.DHPrivateKey; 31 import javax.crypto.spec.DHParameterSpec; 32 import javax.crypto.spec.DHPrivateKeySpec; 33 34 import org.apache.geronimo.util.asn1.ASN1Sequence; 35 import org.apache.geronimo.util.asn1.DEREncodable; 36 import org.apache.geronimo.util.asn1.DERInteger; 37 import org.apache.geronimo.util.asn1.DERObjectIdentifier; 38 import org.apache.geronimo.util.asn1.DEROutputStream; 39 import org.apache.geronimo.util.asn1.pkcs.DHParameter; 40 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers; 41 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo; 42 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier; 43 import org.apache.geronimo.util.crypto.params.DHPrivateKeyParameters; 44 import org.apache.geronimo.util.jce.interfaces.PKCS12BagAttributeCarrier; 45 46 public class JCEDHPrivateKey 47 implements DHPrivateKey, PKCS12BagAttributeCarrier 48 { 49 BigInteger x; 50 51 DHParameterSpec dhSpec; 52 53 private Hashtable pkcs12Attributes = new Hashtable(); 54 private Vector pkcs12Ordering = new Vector(); 55 56 protected JCEDHPrivateKey() 57 { 58 } 59 60 JCEDHPrivateKey( 61 DHPrivateKey key) 62 { 63 this.x = key.getX(); 64 this.dhSpec = key.getParams(); 65 } 66 67 JCEDHPrivateKey( 68 DHPrivateKeySpec spec) 69 { 70 this.x = spec.getX(); 71 this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); 72 } 73 74 JCEDHPrivateKey( 75 PrivateKeyInfo info) 76 { 77 DHParameter params = new DHParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); 78 DERInteger derX = (DERInteger)info.getPrivateKey(); 79 80 this.x = derX.getValue(); 81 if (params.getL() != null) 82 { 83 this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); 84 } 85 else 86 { 87 this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); 88 } 89 } 90 91 JCEDHPrivateKey( 92 DHPrivateKeyParameters params) 93 { 94 this.x = params.getX(); 95 this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG()); 96 } 97 98 public String getAlgorithm() 99 { 100 return "DH"; 101 } 102 103 /** 104 * return the encoding format we produce in getEncoded(). 105 * 106 * @return the string "PKCS#8" 107 */ 108 public String getFormat() 109 { 110 return "PKCS#8"; 111 } 112 113 /** 114 * Return a PKCS8 representation of the key. The sequence returned 115 * represents a full PrivateKeyInfo object. 116 * 117 * @return a PKCS8 representation of the key. 118 */ 119 public byte[] getEncoded() 120 { 121 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 122 DEROutputStream dOut = new DEROutputStream(bOut); 123 PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).getDERObject()), new DERInteger(getX())); 124 125 try 126 { 127 dOut.writeObject(info); 128 dOut.close(); 129 } 130 catch (IOException e) 131 { 132 throw new RuntimeException("Error encoding DH private key"); 133 } 134 135 return bOut.toByteArray(); 136 } 137 138 public DHParameterSpec getParams() 139 { 140 return dhSpec; 141 } 142 143 public BigInteger getX() 144 { 145 return x; 146 } 147 148 private void readObject( 149 ObjectInputStream in) 150 throws IOException, ClassNotFoundException 151 { 152 x = (BigInteger)in.readObject(); 153 154 this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); 155 } 156 157 private void writeObject( 158 ObjectOutputStream out) 159 throws IOException 160 { 161 out.writeObject(this.getX()); 162 out.writeObject(dhSpec.getP()); 163 out.writeObject(dhSpec.getG()); 164 out.writeInt(dhSpec.getL()); 165 } 166 167 public void setBagAttribute( 168 DERObjectIdentifier oid, 169 DEREncodable attribute) 170 { 171 pkcs12Attributes.put(oid, attribute); 172 pkcs12Ordering.addElement(oid); 173 } 174 175 public DEREncodable getBagAttribute( 176 DERObjectIdentifier oid) 177 { 178 return (DEREncodable)pkcs12Attributes.get(oid); 179 } 180 181 public Enumeration getBagAttributeKeys() 182 { 183 return pkcs12Ordering.elements(); 184 } 185 }