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.io.ObjectInputStream; 024 import java.io.ObjectOutputStream; 025 import java.math.BigInteger; 026 import java.util.Enumeration; 027 import java.util.Hashtable; 028 import java.util.Vector; 029 030 import javax.crypto.interfaces.DHPrivateKey; 031 import javax.crypto.spec.DHParameterSpec; 032 import javax.crypto.spec.DHPrivateKeySpec; 033 034 import org.apache.geronimo.util.asn1.ASN1Sequence; 035 import org.apache.geronimo.util.asn1.DEREncodable; 036 import org.apache.geronimo.util.asn1.DERInteger; 037 import org.apache.geronimo.util.asn1.DERObjectIdentifier; 038 import org.apache.geronimo.util.asn1.DEROutputStream; 039 import org.apache.geronimo.util.asn1.pkcs.DHParameter; 040 import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers; 041 import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo; 042 import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier; 043 import org.apache.geronimo.util.crypto.params.DHPrivateKeyParameters; 044 import org.apache.geronimo.util.jce.interfaces.PKCS12BagAttributeCarrier; 045 046 public class JCEDHPrivateKey 047 implements DHPrivateKey, PKCS12BagAttributeCarrier 048 { 049 BigInteger x; 050 051 DHParameterSpec dhSpec; 052 053 private Hashtable pkcs12Attributes = new Hashtable(); 054 private Vector pkcs12Ordering = new Vector(); 055 056 protected JCEDHPrivateKey() 057 { 058 } 059 060 JCEDHPrivateKey( 061 DHPrivateKey key) 062 { 063 this.x = key.getX(); 064 this.dhSpec = key.getParams(); 065 } 066 067 JCEDHPrivateKey( 068 DHPrivateKeySpec spec) 069 { 070 this.x = spec.getX(); 071 this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); 072 } 073 074 JCEDHPrivateKey( 075 PrivateKeyInfo info) 076 { 077 DHParameter params = new DHParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); 078 DERInteger derX = (DERInteger)info.getPrivateKey(); 079 080 this.x = derX.getValue(); 081 if (params.getL() != null) 082 { 083 this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); 084 } 085 else 086 { 087 this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); 088 } 089 } 090 091 JCEDHPrivateKey( 092 DHPrivateKeyParameters params) 093 { 094 this.x = params.getX(); 095 this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG()); 096 } 097 098 public String getAlgorithm() 099 { 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 }