001: /*
002: * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.security.pkcs;
027:
028: import java.io.*;
029: import sun.security.x509.*;
030: import sun.security.util.DerValue;
031: import sun.security.util.DerOutputStream;
032:
033: /**
034: * This class implements the <code>EncryptedPrivateKeyInfo</code> type,
035: * which is defined in PKCS #8 as follows:
036: *
037: * <pre>
038: * EncryptedPrivateKeyInfo ::= SEQUENCE {
039: * encryptionAlgorithm AlgorithmIdentifier,
040: * encryptedData OCTET STRING }
041: * </pre>
042: *
043: * @author Jan Luehe
044: *
045: * @version 1.18, 07/05/05
046: */
047:
048: public class EncryptedPrivateKeyInfo {
049:
050: // the "encryptionAlgorithm" field
051: private AlgorithmId algid;
052:
053: // the "encryptedData" field
054: private byte[] encryptedData;
055:
056: // the ASN.1 encoded contents of this class
057: private byte[] encoded;
058:
059: /**
060: * Constructs (i.e., parses) an <code>EncryptedPrivateKeyInfo</code> from
061: * its encoding.
062: */
063: public EncryptedPrivateKeyInfo(byte[] encoded) throws IOException {
064: if (encoded == null) {
065: throw new IllegalArgumentException(
066: "encoding must not be null");
067: }
068:
069: DerValue val = new DerValue(encoded);
070:
071: DerValue[] seq = new DerValue[2];
072:
073: seq[0] = val.data.getDerValue();
074: seq[1] = val.data.getDerValue();
075:
076: if (val.data.available() != 0) {
077: throw new IOException("overrun, bytes = "
078: + val.data.available());
079: }
080:
081: this .algid = AlgorithmId.parse(seq[0]);
082: if (seq[0].data.available() != 0) {
083: throw new IOException("encryptionAlgorithm field overrun");
084: }
085:
086: this .encryptedData = seq[1].getOctetString();
087: if (seq[1].data.available() != 0)
088: throw new IOException("encryptedData field overrun");
089:
090: this .encoded = (byte[]) encoded.clone();
091: }
092:
093: /**
094: * Constructs an <code>EncryptedPrivateKeyInfo</code> from the
095: * encryption algorithm and the encrypted data.
096: */
097: public EncryptedPrivateKeyInfo(AlgorithmId algid,
098: byte[] encryptedData) {
099: this .algid = algid;
100: this .encryptedData = (byte[]) encryptedData.clone();
101: }
102:
103: /**
104: * Returns the encryption algorithm.
105: */
106: public AlgorithmId getAlgorithm() {
107: return this .algid;
108: }
109:
110: /**
111: * Returns the encrypted data.
112: */
113: public byte[] getEncryptedData() {
114: return (byte[]) this .encryptedData.clone();
115: }
116:
117: /**
118: * Returns the ASN.1 encoding of this class.
119: */
120: public byte[] getEncoded() throws IOException {
121: if (this .encoded != null)
122: return (byte[]) this .encoded.clone();
123:
124: DerOutputStream out = new DerOutputStream();
125: DerOutputStream tmp = new DerOutputStream();
126:
127: // encode encryption algorithm
128: algid.encode(tmp);
129:
130: // encode encrypted data
131: tmp.putOctetString(encryptedData);
132:
133: // wrap everything into a SEQUENCE
134: out.write(DerValue.tag_Sequence, tmp);
135: this .encoded = out.toByteArray();
136:
137: return (byte[]) this .encoded.clone();
138: }
139:
140: public boolean equals(Object other) {
141: if (this == other)
142: return true;
143: if (!(other instanceof EncryptedPrivateKeyInfo))
144: return false;
145: try {
146: byte[] this EncrInfo = this .getEncoded();
147: byte[] otherEncrInfo = ((EncryptedPrivateKeyInfo) other)
148: .getEncoded();
149:
150: if (this EncrInfo.length != otherEncrInfo.length)
151: return false;
152: for (int i = 0; i < this EncrInfo.length; i++)
153: if (this EncrInfo[i] != otherEncrInfo[i])
154: return false;
155: return true;
156: } catch (IOException e) {
157: return false;
158: }
159: }
160:
161: /**
162: * Returns a hashcode for this EncryptedPrivateKeyInfo.
163: *
164: * @return a hashcode for this EncryptedPrivateKeyInfo.
165: */
166: public int hashCode() {
167: int retval = 0;
168:
169: for (int i = 0; i < this.encryptedData.length; i++)
170: retval += this.encryptedData[i] * i;
171: return retval;
172: }
173: }
|