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.provider; 019 020 import java.io.ByteArrayOutputStream; 021 import java.io.IOException; 022 import java.io.ObjectInputStream; 023 import java.io.ObjectOutputStream; 024 import java.math.BigInteger; 025 import java.util.Enumeration; 026 import java.util.Hashtable; 027 import java.util.Vector; 028 029 import javax.crypto.interfaces.DHPrivateKey; 030 import javax.crypto.spec.DHParameterSpec; 031 import javax.crypto.spec.DHPrivateKeySpec; 032 033 import org.apache.geronimo.util.asn1.ASN1Sequence; 034 import org.apache.geronimo.util.asn1.DEREncodable; 035 import org.apache.geronimo.util.asn1.DERInteger; 036 import org.apache.geronimo.util.asn1.DERObjectIdentifier; 037 import org.apache.geronimo.util.asn1.DEROutputStream; 038 import org.apache.geronimo.util.asn1.pkcs.DHParameter; 039 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers; 040 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo; 041 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier; 042 import org.apache.geronimo.util.crypto.params.DHPrivateKeyParameters; 043 import org.apache.geronimo.util.jce.interfaces.PKCS12BagAttributeCarrier; 044 045 public class JCEDHPrivateKey 046 implements DHPrivateKey, PKCS12BagAttributeCarrier 047 { 048 BigInteger x; 049 050 DHParameterSpec dhSpec; 051 052 private Hashtable pkcs12Attributes = new Hashtable(); 053 private Vector pkcs12Ordering = new Vector(); 054 055 protected JCEDHPrivateKey() 056 { 057 } 058 059 JCEDHPrivateKey( 060 DHPrivateKey key) 061 { 062 this.x = key.getX(); 063 this.dhSpec = key.getParams(); 064 } 065 066 JCEDHPrivateKey( 067 DHPrivateKeySpec spec) 068 { 069 this.x = spec.getX(); 070 this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); 071 } 072 073 JCEDHPrivateKey( 074 PrivateKeyInfo info) 075 { 076 DHParameter params = new DHParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); 077 DERInteger derX = (DERInteger)info.getPrivateKey(); 078 079 this.x = derX.getValue(); 080 if (params.getL() != null) 081 { 082 this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); 083 } 084 else 085 { 086 this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); 087 } 088 } 089 090 JCEDHPrivateKey( 091 DHPrivateKeyParameters params) 092 { 093 this.x = params.getX(); 094 this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG()); 095 } 096 097 public String getAlgorithm() 098 { 099 return "DH"; 100 } 101 102 /** 103 * return the encoding format we produce in getEncoded(). 104 * 105 * @return the string "PKCS#8" 106 */ 107 public String getFormat() 108 { 109 return "PKCS#8"; 110 } 111 112 /** 113 * Return a PKCS8 representation of the key. The sequence returned 114 * represents a full PrivateKeyInfo object. 115 * 116 * @return a PKCS8 representation of the key. 117 */ 118 public byte[] getEncoded() 119 { 120 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 121 DEROutputStream dOut = new DEROutputStream(bOut); 122 PrivateKeyInfo info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).getDERObject()), new DERInteger(getX())); 123 124 try 125 { 126 dOut.writeObject(info); 127 dOut.close(); 128 } 129 catch (IOException e) 130 { 131 throw new RuntimeException("Error encoding DH private key", e); 132 } 133 134 return bOut.toByteArray(); 135 } 136 137 public DHParameterSpec getParams() 138 { 139 return dhSpec; 140 } 141 142 public BigInteger getX() 143 { 144 return x; 145 } 146 147 private void readObject( 148 ObjectInputStream in) 149 throws IOException, ClassNotFoundException 150 { 151 x = (BigInteger)in.readObject(); 152 153 this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); 154 } 155 156 private void writeObject( 157 ObjectOutputStream out) 158 throws IOException 159 { 160 out.writeObject(this.getX()); 161 out.writeObject(dhSpec.getP()); 162 out.writeObject(dhSpec.getG()); 163 out.writeInt(dhSpec.getL()); 164 } 165 166 public void setBagAttribute( 167 DERObjectIdentifier oid, 168 DEREncodable attribute) 169 { 170 pkcs12Attributes.put(oid, attribute); 171 pkcs12Ordering.addElement(oid); 172 } 173 174 public DEREncodable getBagAttribute( 175 DERObjectIdentifier oid) 176 { 177 return (DEREncodable)pkcs12Attributes.get(oid); 178 } 179 180 public Enumeration getBagAttributeKeys() 181 { 182 return pkcs12Ordering.elements(); 183 } 184 }