001: package org.bouncycastle.jce.provider;
002:
003: import org.bouncycastle.asn1.ASN1Sequence;
004: import org.bouncycastle.asn1.DERObjectIdentifier;
005: import org.bouncycastle.asn1.DEROctetString;
006: import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
007: import org.bouncycastle.asn1.cryptopro.GOST3410NamedParameters;
008: import org.bouncycastle.asn1.cryptopro.GOST3410ParamSetParameters;
009: import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
010: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
011: import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
012: import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters;
013: import org.bouncycastle.jce.interfaces.GOST3410Params;
014: import org.bouncycastle.jce.interfaces.GOST3410PublicKey;
015: import org.bouncycastle.jce.spec.GOST3410ParameterSpec;
016: import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec;
017: import org.bouncycastle.jce.spec.GOST3410PublicKeySpec;
018:
019: import java.io.IOException;
020: import java.math.BigInteger;
021:
022: public class JDKGOST3410PublicKey implements GOST3410PublicKey {
023: private BigInteger y;
024: private GOST3410Params gost3410Spec;
025:
026: JDKGOST3410PublicKey(GOST3410PublicKeySpec spec) {
027: this .y = spec.getY();
028: this .gost3410Spec = new GOST3410ParameterSpec(
029: new GOST3410PublicKeyParameterSetSpec(spec.getP(), spec
030: .getQ(), spec.getA()));
031: }
032:
033: JDKGOST3410PublicKey(GOST3410PublicKey key) {
034: this .y = key.getY();
035: this .gost3410Spec = key.getParameters();
036: }
037:
038: JDKGOST3410PublicKey(GOST3410PublicKeyParameters params,
039: GOST3410ParameterSpec spec) {
040: this .y = params.getY();
041: this .gost3410Spec = spec;
042: }
043:
044: JDKGOST3410PublicKey(BigInteger y,
045: GOST3410ParameterSpec gost3410Spec) {
046: this .y = y;
047: this .gost3410Spec = gost3410Spec;
048: }
049:
050: JDKGOST3410PublicKey(SubjectPublicKeyInfo info) {
051: GOST3410PublicKeyAlgParameters params = new GOST3410PublicKeyAlgParameters(
052: (ASN1Sequence) info.getAlgorithmId().getParameters());
053: DEROctetString derY;
054:
055: try {
056: derY = (DEROctetString) info.getPublicKey();
057:
058: byte[] keyEnc = derY.getOctets();
059: byte[] keyBytes = new byte[keyEnc.length];
060:
061: for (int i = 0; i != keyEnc.length; i++) {
062: keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // was little endian
063: }
064:
065: this .y = new BigInteger(1, keyBytes);
066: } catch (IOException e) {
067: throw new IllegalArgumentException(
068: "invalid info structure in GOST3410 public key");
069: }
070:
071: GOST3410ParamSetParameters p = GOST3410NamedParameters
072: .getByOID(params.getPublicKeyParamSet());
073:
074: if (params.getEncryptionParamSet() != null) {
075: this .gost3410Spec = new GOST3410ParameterSpec(params
076: .getPublicKeyParamSet().getId(), params
077: .getDigestParamSet().getId(), params
078: .getEncryptionParamSet().getId());
079: } else {
080: this .gost3410Spec = new GOST3410ParameterSpec(params
081: .getPublicKeyParamSet().getId(), params
082: .getDigestParamSet().getId());
083: }
084: }
085:
086: public String getAlgorithm() {
087: return "GOST3410";
088: }
089:
090: public String getFormat() {
091: return "X.509";
092: }
093:
094: public byte[] getEncoded() {
095: SubjectPublicKeyInfo info;
096: byte[] keyEnc = this .getY().toByteArray();
097: byte[] keyBytes;
098:
099: if (keyEnc[0] == 0) {
100: keyBytes = new byte[keyEnc.length - 1];
101: } else {
102: keyBytes = new byte[keyEnc.length];
103: }
104:
105: for (int i = 0; i != keyBytes.length; i++) {
106: keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // must be little endian
107: }
108:
109: if (gost3410Spec instanceof GOST3410ParameterSpec) {
110: if (gost3410Spec.getEncryptionParamSetOID() != null) {
111: info = new SubjectPublicKeyInfo(
112: new AlgorithmIdentifier(
113: CryptoProObjectIdentifiers.gostR3410_94,
114: new GOST3410PublicKeyAlgParameters(
115: new DERObjectIdentifier(
116: gost3410Spec
117: .getPublicKeyParamSetOID()),
118: new DERObjectIdentifier(
119: gost3410Spec
120: .getDigestParamSetOID()),
121: new DERObjectIdentifier(
122: gost3410Spec
123: .getEncryptionParamSetOID()))
124: .getDERObject()),
125: new DEROctetString(keyBytes));
126: } else {
127: info = new SubjectPublicKeyInfo(
128: new AlgorithmIdentifier(
129: CryptoProObjectIdentifiers.gostR3410_94,
130: new GOST3410PublicKeyAlgParameters(
131: new DERObjectIdentifier(
132: gost3410Spec
133: .getPublicKeyParamSetOID()),
134: new DERObjectIdentifier(
135: gost3410Spec
136: .getDigestParamSetOID()))
137: .getDERObject()),
138: new DEROctetString(keyBytes));
139: }
140: } else {
141: info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(
142: CryptoProObjectIdentifiers.gostR3410_94),
143: new DEROctetString(keyBytes));
144: }
145:
146: return info.getDEREncoded();
147: }
148:
149: public GOST3410Params getParameters() {
150: return gost3410Spec;
151: }
152:
153: public BigInteger getY() {
154: return y;
155: }
156:
157: public String toString() {
158: StringBuffer buf = new StringBuffer();
159: String nl = System.getProperty("line.separator");
160:
161: buf.append("GOST3410 Public Key").append(nl);
162: buf.append(" y: ").append(this .getY().toString(16))
163: .append(nl);
164:
165: return buf.toString();
166: }
167:
168: public boolean equals(Object o) {
169: if (o instanceof JDKGOST3410PublicKey) {
170: JDKGOST3410PublicKey other = (JDKGOST3410PublicKey) o;
171:
172: return this .y.equals(other.y)
173: && this .gost3410Spec.equals(other.gost3410Spec);
174: }
175:
176: return false;
177: }
178:
179: public int hashCode() {
180: return y.hashCode() ^ gost3410Spec.hashCode();
181: }
182: }
|