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.crypto.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 026 import javax.crypto.interfaces.DHPublicKey; 027 import javax.crypto.spec.DHParameterSpec; 028 import javax.crypto.spec.DHPublicKeySpec; 029 030 import org.apache.geronimo.crypto.asn1.ASN1Sequence; 031 import org.apache.geronimo.crypto.asn1.DERInteger; 032 import org.apache.geronimo.crypto.asn1.DEROutputStream; 033 import org.apache.geronimo.crypto.asn1.pkcs.DHParameter; 034 import org.apache.geronimo.crypto.asn1.x509.AlgorithmIdentifier; 035 import org.apache.geronimo.crypto.asn1.x509.SubjectPublicKeyInfo; 036 import org.apache.geronimo.crypto.asn1.x9.X9ObjectIdentifiers; 037 import org.apache.geronimo.crypto.crypto.params.DHPublicKeyParameters; 038 039 public class JCEDHPublicKey 040 implements DHPublicKey 041 { 042 private BigInteger y; 043 private DHParameterSpec dhSpec; 044 045 JCEDHPublicKey( 046 DHPublicKeySpec spec) 047 { 048 this.y = spec.getY(); 049 this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); 050 } 051 052 JCEDHPublicKey( 053 DHPublicKey key) 054 { 055 this.y = key.getY(); 056 this.dhSpec = key.getParams(); 057 } 058 059 JCEDHPublicKey( 060 DHPublicKeyParameters params) 061 { 062 this.y = params.getY(); 063 this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), 0); 064 } 065 066 JCEDHPublicKey( 067 BigInteger y, 068 DHParameterSpec dhSpec) 069 { 070 this.y = y; 071 this.dhSpec = dhSpec; 072 } 073 074 JCEDHPublicKey( 075 SubjectPublicKeyInfo info) 076 { 077 DHParameter params = new DHParameter((ASN1Sequence)info.getAlgorithmId().getParameters()); 078 DERInteger derY = null; 079 080 try 081 { 082 derY = (DERInteger)info.getPublicKey(); 083 } 084 catch (IOException e) 085 { 086 throw new IllegalArgumentException("invalid info structure in DH public key", e); 087 } 088 089 this.y = derY.getValue(); 090 if (params.getL() != null) 091 { 092 this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); 093 } 094 else 095 { 096 this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); 097 } 098 } 099 100 public String getAlgorithm() 101 { 102 return "DH"; 103 } 104 105 public String getFormat() 106 { 107 return "X.509"; 108 } 109 110 public byte[] getEncoded() 111 { 112 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 113 DEROutputStream dOut = new DEROutputStream(bOut); 114 SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.dhpublicnumber, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).getDERObject()), new DERInteger(y)); 115 116 try 117 { 118 dOut.writeObject(info); 119 dOut.close(); 120 } 121 catch (IOException e) 122 { 123 throw new RuntimeException("Error encoding DH public key", e); 124 } 125 126 return bOut.toByteArray(); 127 128 } 129 130 public DHParameterSpec getParams() 131 { 132 return dhSpec; 133 } 134 135 public BigInteger getY() 136 { 137 return y; 138 } 139 140 private void readObject( 141 ObjectInputStream in) 142 throws IOException, ClassNotFoundException 143 { 144 this.y = (BigInteger)in.readObject(); 145 this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); 146 } 147 148 private void writeObject( 149 ObjectOutputStream out) 150 throws IOException 151 { 152 out.writeObject(this.getY()); 153 out.writeObject(dhSpec.getP()); 154 out.writeObject(dhSpec.getG()); 155 out.writeInt(dhSpec.getL()); 156 } 157 }