001: package org.bouncycastle.jce.provider;
002:
003: import org.bouncycastle.asn1.ASN1Sequence;
004: import org.bouncycastle.asn1.DEREncodable;
005: import org.bouncycastle.asn1.DERObjectIdentifier;
006: import org.bouncycastle.asn1.DEROctetString;
007: import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
008: import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
009: import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
010: import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
011: import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters;
012: import org.bouncycastle.jce.interfaces.GOST3410Params;
013: import org.bouncycastle.jce.interfaces.GOST3410PrivateKey;
014: import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
015: import org.bouncycastle.jce.spec.GOST3410ParameterSpec;
016: import org.bouncycastle.jce.spec.GOST3410PrivateKeySpec;
017: import org.bouncycastle.jce.spec.GOST3410PublicKeyParameterSetSpec;
018:
019: import java.math.BigInteger;
020: import java.util.Enumeration;
021:
022: public class JDKGOST3410PrivateKey implements GOST3410PrivateKey,
023: PKCS12BagAttributeCarrier {
024: BigInteger x;
025: GOST3410Params gost3410Spec;
026:
027: private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
028:
029: protected JDKGOST3410PrivateKey() {
030: }
031:
032: JDKGOST3410PrivateKey(GOST3410PrivateKey key) {
033: this .x = key.getX();
034: this .gost3410Spec = key.getParameters();
035: }
036:
037: JDKGOST3410PrivateKey(GOST3410PrivateKeySpec spec) {
038: this .x = spec.getX();
039: this .gost3410Spec = new GOST3410ParameterSpec(
040: new GOST3410PublicKeyParameterSetSpec(spec.getP(), spec
041: .getQ(), spec.getA()));
042: }
043:
044: JDKGOST3410PrivateKey(PrivateKeyInfo info) {
045: GOST3410PublicKeyAlgParameters params = new GOST3410PublicKeyAlgParameters(
046: (ASN1Sequence) info.getAlgorithmId().getParameters());
047: DEROctetString derX = (DEROctetString) info.getPrivateKey();
048: byte[] keyEnc = derX.getOctets();
049: byte[] keyBytes = new byte[keyEnc.length];
050:
051: for (int i = 0; i != keyEnc.length; i++) {
052: keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // was little endian
053: }
054:
055: this .x = new BigInteger(1, keyBytes);
056:
057: if (params.getEncryptionParamSet() != null) {
058: this .gost3410Spec = new GOST3410ParameterSpec(params
059: .getPublicKeyParamSet().getId(), params
060: .getDigestParamSet().getId(), params
061: .getEncryptionParamSet().getId());
062: } else {
063: this .gost3410Spec = new GOST3410ParameterSpec(params
064: .getPublicKeyParamSet().getId(), params
065: .getDigestParamSet().getId());
066: }
067: }
068:
069: JDKGOST3410PrivateKey(GOST3410PrivateKeyParameters params,
070: GOST3410ParameterSpec spec) {
071: this .x = params.getX();
072: this .gost3410Spec = spec;
073:
074: if (spec == null) {
075: throw new IllegalArgumentException("spec is null");
076: }
077: }
078:
079: public String getAlgorithm() {
080: return "GOST3410";
081: }
082:
083: /**
084: * return the encoding format we produce in getEncoded().
085: *
086: * @return the string "PKCS#8"
087: */
088: public String getFormat() {
089: return "PKCS#8";
090: }
091:
092: /**
093: * Return a PKCS8 representation of the key. The sequence returned
094: * represents a full PrivateKeyInfo object.
095: *
096: * @return a PKCS8 representation of the key.
097: */
098: public byte[] getEncoded() {
099: PrivateKeyInfo info;
100: byte[] keyEnc = this .getX().toByteArray();
101: byte[] keyBytes;
102:
103: if (keyEnc[0] == 0) {
104: keyBytes = new byte[keyEnc.length - 1];
105: } else {
106: keyBytes = new byte[keyEnc.length];
107: }
108:
109: for (int i = 0; i != keyBytes.length; i++) {
110: keyBytes[i] = keyEnc[keyEnc.length - 1 - i]; // must be little endian
111: }
112:
113: if (gost3410Spec instanceof GOST3410ParameterSpec) {
114: info = new PrivateKeyInfo(new AlgorithmIdentifier(
115: CryptoProObjectIdentifiers.gostR3410_94,
116: new GOST3410PublicKeyAlgParameters(
117: new DERObjectIdentifier(gost3410Spec
118: .getPublicKeyParamSetOID()),
119: new DERObjectIdentifier(gost3410Spec
120: .getDigestParamSetOID()))
121: .getDERObject()), new DEROctetString(
122: keyBytes));
123: } else {
124: info = new PrivateKeyInfo(new AlgorithmIdentifier(
125: CryptoProObjectIdentifiers.gostR3410_94),
126: new DEROctetString(keyBytes));
127: }
128:
129: return info.getDEREncoded();
130: }
131:
132: public GOST3410Params getParameters() {
133: return gost3410Spec;
134: }
135:
136: public BigInteger getX() {
137: return x;
138: }
139:
140: public void setBagAttribute(DERObjectIdentifier oid,
141: DEREncodable attribute) {
142: attrCarrier.setBagAttribute(oid, attribute);
143: }
144:
145: public DEREncodable getBagAttribute(DERObjectIdentifier oid) {
146: return attrCarrier.getBagAttribute(oid);
147: }
148:
149: public Enumeration getBagAttributeKeys() {
150: return attrCarrier.getBagAttributeKeys();
151: }
152: }
|