Index: modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/CryptoProvider.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/CryptoProvider.java (revision 452797) +++ modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/CryptoProvider.java (working copy) @@ -49,6 +49,10 @@ final String SIGN_ALIAS = "SHA1withDSA"; //$NON-NLS-1$ + + final String KEYF_NAME = + "org.apache.harmony.security.provider.crypto.DSAKeyFactoryImpl"; //$NON-NLS-1$ + AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { @@ -78,6 +82,11 @@ put("Alg.Alias.Signature.1.3.14.3.2.13", SIGN_ALIAS); //$NON-NLS-1$ put("Alg.Alias.Signature.1.3.14.3.2.27", SIGN_ALIAS); //$NON-NLS-1$ + put("KeyFactory.DSA", KEYF_NAME); //$NON-NLS-1$ + put("KeyFactory.DSA ImplementedIn", "Software"); //$NON-NLS-1$ //$NON-NLS-2$ + put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); //$NON-NLS-1$ //$NON-NLS-2$ + put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA"); //$NON-NLS-1$ //$NON-NLS-2$ + return null; } }); Index: modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAKeyFactoryImpl.java (revision 0) @@ -0,0 +1,256 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.harmony.security.provider.crypto; + + +import java.io.IOException; + +import java.math.BigInteger; + +import java.security.KeyFactorySpi; +import java.security.Key; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.InvalidKeyException; + +import java.security.spec.KeySpec; +import java.security.spec.DSAParameterSpec; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; + +import org.apache.harmony.security.provider.crypto.DSAPrivateKeyImpl; +import org.apache.harmony.security.provider.crypto.DSAPublicKeyImpl; + +import org.apache.harmony.security.asn1.ASN1Sequence; +import org.apache.harmony.security.asn1.ASN1Integer; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.asn1.ASN1BitString; +import org.apache.harmony.security.asn1.BitString; +import org.apache.harmony.security.asn1.ASN1OctetString; + +import org.apache.harmony.security.internal.nls.Messages; + +import org.apache.harmony.crypto.utils.AlgNameMapper; + + +public class DSAKeyFactoryImpl extends KeyFactorySpi { + + + /** + * The method generates a DSAPrivateKey object from the provided key specification. + * + * @param + * keySpec - the specification (key material) for the DSAPrivateKey. + * + * @return + * a DSAPrivateKey object + * + * @throws InvalidKeySpecException + * if "keySpec" is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec + */ + protected PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException { + + if ( keySpec != null ) { + if ( keySpec instanceof DSAPrivateKeySpec ) { + + return new DSAPrivateKeyImpl((DSAPrivateKeySpec) keySpec); + } + if ( keySpec instanceof PKCS8EncodedKeySpec ) { + + return new DSAPrivateKeyImpl((PKCS8EncodedKeySpec) keySpec); + } + } + throw new InvalidKeySpecException(Messages.getString("security.19C")); //$NON-NLS-1$ + } + + + /** + * The method generates a DSAPublicKey object from the provided key specification. + * + * @param + * keySpec - the specification (key material) for the DSAPublicKey. + * + * @return + * a DSAPublicKey object + * + * @throws InvalidKeySpecException + * if "keySpec" is neither DSAPublicKeySpec nor X509EncodedKeySpec + */ + protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { + + if ( keySpec != null ) { + if ( keySpec instanceof DSAPublicKeySpec ) { + + return new DSAPublicKeyImpl( (DSAPublicKeySpec) keySpec ); + } + if ( keySpec instanceof X509EncodedKeySpec ) { + + return new DSAPublicKeyImpl( (X509EncodedKeySpec) keySpec ); + } + } + throw new InvalidKeySpecException(Messages.getString("security.19D")); //$NON-NLS-1$ + } + + + /** + * The method returns a specification (key material) of the given key object. + * 'keySpec' identifies the specification class + * in which the key material should be returned. + * + * If it is DSAPublicKeySpec.class, the key material should be returned + * in an instance of the DSAPublicKeySpec class; + * if it is DSAPrivateKeySpec.class, the key material should be returned + * in an instance of the DSAPrivateKeySpec class. + * + * @param + * key - either DSAPrivateKey or DSAPublicKey + * @param + * keySpec - either DSAPublicKeySpec.class or DSAPublicKeySpec.class + * + * @return + * either DSAPublicKeySpec object or DSAPublicKeySpec object + * + * @throws InvalidKeySpecException + * if "keySpec" is not s specification for DSAPublicKey or DSAPrivateKey + * + */ + protected T engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException { + + BigInteger p, q, g, x, y; + + if ( key != null ) { + if ( keySpec == null ) { + throw new NullPointerException( + Messages.getString("security.19E")); //$NON-NLS-1$ + } + if ( key instanceof DSAPrivateKey ) { + DSAPrivateKey privateKey = (DSAPrivateKey) key; + + if ( keySpec.equals(DSAPrivateKeySpec.class) ) { + + x = privateKey.getX(); + + DSAParams params = privateKey.getParams(); + + p = params.getP(); + q = params.getQ(); + g = params.getG(); + + return (T)( new DSAPrivateKeySpec(x, p, q, g) ); + } + + if ( keySpec.equals(PKCS8EncodedKeySpec.class) ) { + return (T)( new PKCS8EncodedKeySpec(key.getEncoded()) ); + } + + throw new InvalidKeySpecException( + Messages.getString("security.19C")); //$NON-NLS-1$ + } + + if ( key instanceof DSAPublicKey ) { + DSAPublicKey publicKey = (DSAPublicKey) key; + + if ( keySpec.equals(DSAPublicKeySpec.class) ) { + + y = publicKey.getY(); + + DSAParams params = publicKey.getParams(); + + p = params.getP(); + q = params.getQ(); + g = params.getG(); + + return (T)( new DSAPublicKeySpec(y, p, q, g) ); + } + + if ( keySpec.equals(X509EncodedKeySpec.class) ) { + return (T)( new X509EncodedKeySpec(key.getEncoded()) ); + } + + throw new InvalidKeySpecException( + Messages.getString("security.19D")); //$NON-NLS-1$ + } + } + throw new InvalidKeySpecException(Messages.getString("security.19F")); //$NON-NLS-1$ + } + + + /** + * The method generates a DSAPublicKey object from the provided key. + * + * @param + * key - a DSAPublicKey object or DSAPrivateKey object. + * + * @return + * object of the same type as the "key" argument + * + * @throws InvalidKeyException + * if "key" is neither DSAPublicKey nor DSAPrivateKey + */ + protected Key engineTranslateKey(Key key) throws InvalidKeyException { + + if ( key != null ) { + if ( key instanceof DSAPrivateKey ) { + + DSAPrivateKey privateKey = (DSAPrivateKey) key; + DSAParams params = privateKey.getParams(); + + try { + return engineGeneratePrivate( new DSAPrivateKeySpec( privateKey.getX(), + params.getP(), + params.getQ(), + params.getG() ) ); + } catch (InvalidKeySpecException e) { + // Actually this exception shouldn't be thrown + throw new InvalidKeyException( + Messages.getString("security.1A0",e)); //$NON-NLS-1$ + } + } + + if ( key instanceof DSAPublicKey ) { + + DSAPublicKey publicKey = (DSAPublicKey) key; + DSAParams params = publicKey.getParams(); + + try { + return engineGeneratePublic( new DSAPublicKeySpec( publicKey.getY(), + params.getP(), + params.getQ(), + params.getG() ) ); + } catch (InvalidKeySpecException e) { + // Actually this exception shouldn't be thrown + throw new InvalidKeyException( + Messages.getString("security.1A1",e)); //$NON-NLS-1$ + } + } + } + throw new InvalidKeyException(Messages.getString("security.19F")); //$NON-NLS-1$ + } + +} Index: modules/security/src/main/java/common/org/apache/harmony/security/PrivateKeyImpl.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/PrivateKeyImpl.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/PrivateKeyImpl.java (revision 0) @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.harmony.security; + + +import java.security.PrivateKey; + + +/** + * PrivateKeyImpl + */ +public class PrivateKeyImpl implements PrivateKey { + + /* + * @serial + */ + private static final long serialVersionUID = 7776497482533790279L; + + private String algorithm; + + private byte[] encoding; + + + public PrivateKeyImpl(String algorithm) { + this.algorithm = algorithm; + } + + + public String getAlgorithm() { + return algorithm; + } + + + public String getFormat() { + return "PKCS#8"; //$NON-NLS-1$ + } + + + public byte[] getEncoded() { + + byte[] toReturn = new byte[encoding.length]; + System.arraycopy(encoding, 0, toReturn, 0, encoding.length); + + return toReturn; + } + + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + + public void setEncoding(byte[] encoding) { + this.encoding = new byte[encoding.length]; + System.arraycopy(encoding, 0, this.encoding, 0, encoding.length); + } + +} Index: modules/security/src/main/java/common/org/apache/harmony/security/PublicKeyImpl.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/PublicKeyImpl.java (revision 452797) +++ modules/security/src/main/java/common/org/apache/harmony/security/PublicKeyImpl.java (working copy) @@ -15,17 +15,11 @@ * limitations under the License. */ -/** -* @author Alexander Y. Kleymenov -* @version $Revision$ -*/ package org.apache.harmony.security; import java.security.PublicKey; -import java.util.Arrays; -import org.apache.harmony.crypto.utils.AlgNameMapper; /** * PublicKeyImpl @@ -37,46 +31,42 @@ */ private static final long serialVersionUID = 7179022516819534075L; - private final byte[] encoding; - private final String algorithm; - - /** - * Constructs the PublicKey instance with specified algorithm oid - * and ASN.1 DER encoded form of SubjectPublicKeyInfo structure - * which is ASN.1 data format for public keys in X.509 standard. - * @param oid : String - * @param encoding : byte[] - */ - public PublicKeyImpl(String oid, byte[] encoding) { - this.encoding = new byte[encoding.length]; - System.arraycopy(encoding, 0, this.encoding, 0, encoding.length); - String alg = AlgNameMapper.map2AlgName(oid); - algorithm = (alg == null) ? oid : alg; + + private byte[] encoding; + + private String algorithm; + + + public PublicKeyImpl(String algorithm) { + this.algorithm = algorithm; } + public String getAlgorithm() { return algorithm; } + public String getFormat() { return "X.509"; //$NON-NLS-1$ } + public byte[] getEncoded() { byte[] result = new byte[encoding.length]; System.arraycopy(encoding, 0, result, 0, encoding.length); return result; } - public boolean equals(Object other) { - if (other == this) { - return true; - } - if (!(other instanceof PublicKey)) { - return false; - } - PublicKey obj = (PublicKey) other; - return Arrays.equals(encoding, obj.getEncoded()); + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; } + + + public void setEncoding(byte[] encoding) { + this.encoding = new byte[encoding.length]; + System.arraycopy(encoding, 0, this.encoding, 0, encoding.length); + } } Index: modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAPrivateKeyImpl.java (revision 0) @@ -0,0 +1,234 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + * TODO + * 1. The class extends the PrivateKeyImpl class in "org.apache.harmony.security" package. + * + * 2. The auxilliary non-public "ThreeIntegerSequence" class defined at the end + * is used by the "DSAPublicKeyImpl" class. + * + * 3. See a compatibility with RI comments + * in the below "DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec)" constructor. + */ + + +package org.apache.harmony.security.provider.crypto; + + +import java.io.IOException; + +import java.math.BigInteger; + +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAParams; + +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.DSAParameterSpec; +import java.security.spec.PKCS8EncodedKeySpec; + +import org.apache.harmony.security.x509.AlgorithmIdentifier; +import org.apache.harmony.security.pkcs8.PrivateKeyInfo; + +import org.apache.harmony.security.asn1.ASN1Sequence; +import org.apache.harmony.security.asn1.ASN1Integer; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.asn1.ASN1BitString; +import org.apache.harmony.security.asn1.BitString; +import org.apache.harmony.security.asn1.ASN1OctetString; + +import org.apache.harmony.security.internal.nls.Messages; +import org.apache.harmony.crypto.utils.AlgNameMapper; + +import org.apache.harmony.security.PrivateKeyImpl; + + +/** + * The class provides DSAPrivateKey functionality by extending a class implementing PrivateKey + * and implementing methods defined in both interfaces, DSAKey and DSAPrivateKey + */ +public class DSAPrivateKeyImpl extends PrivateKeyImpl implements DSAPrivateKey { + + + /** + * @serial + */ + private static final long serialVersionUID = -4716227614104950081L; + + private BigInteger x; + + private DSAParams params; + + + /** + * Creates object from DSAPrivateKeySpec. + * + * @param keySpec - a DSAPrivateKeySpec object + */ + public DSAPrivateKeyImpl(DSAPrivateKeySpec keySpec) { + + super("DSA"); //$NON-NLS-1$ + + PrivateKeyInfo pki; + + BigInteger g = keySpec.getG(); + BigInteger p = keySpec.getP(); + BigInteger q = keySpec.getQ(); + + ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p.toByteArray(), + q.toByteArray(), g.toByteArray() ); + + AlgorithmIdentifier ai = new AlgorithmIdentifier( + AlgNameMapper.map2OID("DSA"), //$NON-NLS-1$ + threeInts.getEncoded() ); + x = keySpec.getX(); + + pki = new PrivateKeyInfo(0, ai, + ASN1Integer.getInstance().encode( x.toByteArray() ), null); + + setEncoding(pki.getEncoded()); + + params = (DSAParams)( new DSAParameterSpec(p, q, g) ); + } + + + /** + * Creates object from PKCS8EncodedKeySpec. + * + * @param keySpec - a XPKCS8EncodedKeySpec object + * + * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format + */ + public DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec) throws InvalidKeySpecException { + + super("DSA"); //$NON-NLS-1$ + + AlgorithmIdentifier ai; + ThreeIntegerSequence threeInts = null; + + String alg, algName; + + byte encoding[] = keySpec.getEncoded(); + + PrivateKeyInfo privateKeyInfo = null; + + + try { + privateKeyInfo = (PrivateKeyInfo) PrivateKeyInfo.ASN1.decode(encoding); + } catch (IOException e) { + throw new InvalidKeySpecException( + Messages.getString("security.19A", e)); //$NON-NLS-1$ + } + + try { + x = new BigInteger( (byte[]) ASN1Integer.getInstance().decode( + privateKeyInfo.getPrivateKey()) ); + } catch (IOException e) { + throw new InvalidKeySpecException( + Messages.getString("security.19B", e)); //$NON-NLS-1$ + } + + ai = privateKeyInfo.getAlgorithmIdentifier(); + try { + threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1.decode( + ai.getParameters()); + } catch (IOException e) { + throw new InvalidKeySpecException( + Messages.getString("security.19B",e)); //$NON-NLS-1$ + } + params = (DSAParams)( new DSAParameterSpec(new BigInteger(threeInts.p), + new BigInteger(threeInts.q), new BigInteger(threeInts.g)) ); + + setEncoding(encoding); + + /* + * the following code implements RI behavior + */ + alg = ai.getAlgorithm(); + algName = AlgNameMapper.map2AlgName(alg); + setAlgorithm(algName == null ? alg : algName); + } + + + public BigInteger getX() { + return x; + } + + + public DSAParams getParams() { + return params; + } + +} + + +/** + * The auxilliary class providing means to process ASN1Sequence of three Integers. + * Such sequenies are parts of ASN1 encoded formats for DSA private and public keys. + */ +class ThreeIntegerSequence { + + byte[] p, q, g; + + private byte[] encoding; + + + ThreeIntegerSequence(byte[] p, byte[] q, byte[] g) { + + this.p = p; + this.q = q; + this.g = g; + encoding = null; + } + + + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(this); + } + return encoding; + } + + + public static final ASN1Sequence ASN1 = new ASN1Sequence( + new ASN1Type[] { ASN1Integer.getInstance(), + ASN1Integer.getInstance(), + ASN1Integer.getInstance() }) { + protected Object getDecodedObject(BerInputStream in) { + + Object[] values = (Object[]) in.content; + + return new ThreeIntegerSequence( + (byte[]) values[0], + (byte[]) values[1], + (byte[]) values[2] ); + } + + protected void getValues(Object object, Object[] values) { + + ThreeIntegerSequence mySeq = (ThreeIntegerSequence) object; + + values[0] = mySeq.p; + values[1] = mySeq.q; + values[2] = mySeq.g; + } + }; +} + + Index: modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/DSAPublicKeyImpl.java (revision 0) @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + /* + * TODO + * 1. The class extends the PublicKeyImpl class in "org.apache.harmony.security" package. + * + * 2. The class uses methods in the auxilliary non-public "ThreeIntegerSequence" class + * defined along with the "DSAPrivateKeyImpl" class. + * + * 3. See a compatibility with RI comments + * in the below "DSAPublicKeyImpl(X509EncodedKeySpec keySpec)" constructor. + */ + +package org.apache.harmony.security.provider.crypto; + + +import java.io.IOException; + +import java.math.BigInteger; + +import java.security.interfaces.DSAPublicKey; +import java.security.interfaces.DSAParams; + +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.DSAParameterSpec; +import java.security.spec.X509EncodedKeySpec; + +import org.apache.harmony.security.x509.AlgorithmIdentifier; +import org.apache.harmony.security.x509.SubjectPublicKeyInfo; + +import org.apache.harmony.security.asn1.ASN1Integer; +//import org.apache.harmony.security.asn1.ASN1Sequence; +//import org.apache.harmony.security.asn1.ASN1Type; +//import org.apache.harmony.security.asn1.BerInputStream; +//import org.apache.harmony.security.asn1.ASN1BitString; +//import org.apache.harmony.security.asn1.BitString; +//import org.apache.harmony.security.asn1.ASN1OctetString; + +import org.apache.harmony.security.internal.nls.Messages; +import org.apache.harmony.crypto.utils.AlgNameMapper; + +import org.apache.harmony.security.PublicKeyImpl; + + +/** + * The class provides DSAPublicKey functionality by extending a class implementing PublicKey + * and implementing methods defined in both interfaces, DSAKey and DSAPublicKey + */ +public class DSAPublicKeyImpl extends PublicKeyImpl implements DSAPublicKey { + + + /** + * @serial + */ + private static final long serialVersionUID = -2279672131310978336L; + + private BigInteger y; + + private DSAParams params; + + + /** + * Creates object from DSAPublicKeySpec. + * + * @param keySpec - a DSAPublicKeySpec object + */ + public DSAPublicKeyImpl(DSAPublicKeySpec keySpec) { + + super("DSA"); //$NON-NLS-1$ + + SubjectPublicKeyInfo spki; + + BigInteger p = keySpec.getP(); + BigInteger q = keySpec.getQ(); + BigInteger g = keySpec.getG(); + + ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p.toByteArray(), + q.toByteArray(), g.toByteArray() ); + + AlgorithmIdentifier ai = new AlgorithmIdentifier( + AlgNameMapper.map2OID("DSA"), //$NON-NLS-1$ + threeInts.getEncoded() ); + + y = keySpec.getY(); + + spki = new SubjectPublicKeyInfo( ai, + ASN1Integer.getInstance().encode(y.toByteArray()) ); + setEncoding(spki.getEncoded()); + + params = (DSAParams)( new DSAParameterSpec(p, q, g) ); + } + + + /** + * Creates object from X509EncodedKeySpec. + * + * @param keySpec - a X509EncodedKeySpec object + * + * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format + */ + public DSAPublicKeyImpl(X509EncodedKeySpec keySpec) throws InvalidKeySpecException { + + super("DSA"); //$NON-NLS-1$ + + AlgorithmIdentifier ai; + ThreeIntegerSequence threeInts = null; + + SubjectPublicKeyInfo subjectPublicKeyInfo = null; + + byte encoding[] = keySpec.getEncoded(); + + String alg, algName; + + + try { + subjectPublicKeyInfo = (SubjectPublicKeyInfo) SubjectPublicKeyInfo.ASN1 + .decode(encoding); + } catch (IOException e) { + throw new InvalidKeySpecException( + Messages.getString("security.19A",e)); //$NON-NLS-1$ + } + + try { + y = new BigInteger( (byte[]) ASN1Integer.getInstance().decode( + subjectPublicKeyInfo.getSubjectPublicKey() )); + } catch (IOException e) { + throw new InvalidKeySpecException( + Messages.getString("security.19B",e)); //$NON-NLS-1$ + } + + ai = subjectPublicKeyInfo.getAlgorithmIdentifier(); + + try { + threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1.decode( + ai.getParameters() ); + } catch (IOException e) { + throw new InvalidKeySpecException( + Messages.getString("security.19B",e)); //$NON-NLS-1$ + } + params = (DSAParams)( new DSAParameterSpec(new BigInteger(threeInts.p), + new BigInteger(threeInts.q), new BigInteger(threeInts.g)) ); + + setEncoding(encoding); + + /* + * the following code implements RI behavior + */ + alg = ai.getAlgorithm(); + algName = AlgNameMapper.map2AlgName(alg); + setAlgorithm(algName == null ? alg : algName); + } + + + /** + * @return + * a value of a public key (y). + */ + public BigInteger getY() { + return y; + } + + + /** + * @return + * DSA key parameters (p, q, g). + */ + public DSAParams getParams() { + return params; + } + +} Index: modules/security/src/main/java/common/org/apache/harmony/security/pkcs8/PrivateKeyInfo.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/pkcs8/PrivateKeyInfo.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/pkcs8/PrivateKeyInfo.java (revision 0) @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.harmony.security.pkcs8; + + +import org.apache.harmony.security.asn1.ASN1Implicit; +import org.apache.harmony.security.asn1.ASN1Integer; +import org.apache.harmony.security.asn1.ASN1OctetString; +import org.apache.harmony.security.asn1.ASN1Sequence; +import org.apache.harmony.security.asn1.ASN1SetOf; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.BerInputStream; + +import org.apache.harmony.security.x501.AttributeTypeAndValue; + +import org.apache.harmony.security.x509.AlgorithmIdentifier; + +import java.util.List; + + +/** + * The class implements the ASN.1 DER encoding and decoding of the PKCS#8 + * PrivateKeyInfo having the following ASN.1 notation: + * + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL } + * + * Version ::= INTEGER + * + * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + * + * PrivateKey ::= OCTET STRING + * + * Attributes ::= SET OF Attribute + */ + + +public class PrivateKeyInfo { + + + private int version; + + private AlgorithmIdentifier privateKeyAlgorithm; + + private byte[] privateKey; + + private List attributes; + + private byte[] encoding; + + + public PrivateKeyInfo(int version, AlgorithmIdentifier privateKeyAlgorithm, + byte[] privateKey, List attributes) { + + this.version = version; + this.privateKeyAlgorithm = privateKeyAlgorithm; + this.privateKey = privateKey; + this.attributes = attributes; + } + + + private PrivateKeyInfo(int version, AlgorithmIdentifier privateKeyAlgorithm, + byte[] privateKey, List attributes, byte [] encoding) { + this(version, privateKeyAlgorithm, privateKey, attributes); + this.encoding = encoding; + } + + + /** + * @return Returns version. + */ + public int getVersion() { + return version; + } + + + /** + * @return Returns AlgorithmIdentifier. + */ + public AlgorithmIdentifier getAlgorithmIdentifier() { + return privateKeyAlgorithm; + } + + + /** + * @return Returns List of attributes. + */ + public List getAttributes() { + return attributes; + } + + + /** + * @return Returns the OCTET STRING. + */ + public byte[] getPrivateKey() { + return privateKey; + } + + + /** + * Returns ASN.1 encoded form of this PrivateKeyInfo. + * @return a byte array containing ASN.1 encode form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(this); + } + return encoding; + } + + + public static final ASN1Sequence ASN1 = new ASN1Sequence( new ASN1Type[] { + + ASN1Integer.getInstance(), // version + AlgorithmIdentifier.ASN1, // AlgorithmIdentifier + ASN1OctetString.getInstance(), // privateKey + + new ASN1Implicit(0, new ASN1SetOf(AttributeTypeAndValue.ASN1) ) // attributes + }) { + + { + setOptional(3); // attributes are OPTIONAL + } + + + protected Object getDecodedObject(BerInputStream in) { + + Object[] values = (Object[]) in.content; + + return new PrivateKeyInfo( + ASN1Integer.toIntValue(values[0]), + (AlgorithmIdentifier) values[1], + (byte[]) values[2], + (List) values[3], + in.getEncoded()); + } + + + protected void getValues(Object object, Object[] values) { + + PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) object; + + values[0] = ASN1Integer.fromIntValue(privateKeyInfo.version); + values[1] = privateKeyInfo.privateKeyAlgorithm; + values[2] = privateKeyInfo.privateKey; + values[3] = privateKeyInfo.attributes; + } + }; + +} Index: modules/security/src/main/java/common/org/apache/harmony/security/internal/nls/messages.properties =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/internal/nls/messages.properties (revision 452797) +++ modules/security/src/main/java/common/org/apache/harmony/security/internal/nls/messages.properties (working copy) @@ -329,3 +329,12 @@ security.9D=ObjectIdentifier string is null security.9E=Incorrect syntax security.9F=Implicit tagging can not be used for ASN.1 ANY or CHOICE type +security.19A=Failed to decode keySpec encoding: {0} +security.19B=Failed to decode parameters: {0} +security.19C='keySpec' is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec +security.19D='keySpec' is neither DSAPublicKeySpec nor X509EncodedKeySpec +security.19E=null is passed to the 'keySpec' argument +security.19F='key' is neither DSAPublicKey nor DSAPrivateKey +security.1A0=ATTENTION: InvalidKeySpecException in engineGeneratePrivate: {0} +security.1A1=ATTENTION: InvalidKeySpecException in engineGeneratePublic: {0} + Index: modules/security/build.xml =================================================================== --- modules/security/build.xml (revision 452797) +++ modules/security/build.xml (working copy) @@ -236,6 +236,7 @@ +