diff options
Diffstat (limited to 'core/src/main/jdk1.1/org/bouncycastle')
21 files changed, 0 insertions, 6016 deletions
diff --git a/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java b/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java deleted file mode 100644 index 7c156266..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1InputStream.java +++ /dev/null @@ -1,466 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.ByteArrayInputStream; -import java.io.EOFException; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.bouncycastle.util.io.Streams; - -/** - * a general purpose ASN.1 decoder - note: this class differs from the - * others in that it returns null after it has read the last object in - * the stream. If an ASN.1 NULL is encountered a DER/BER Null object is - * returned. - */ -public class ASN1InputStream - extends FilterInputStream - implements BERTags -{ - private int limit; - private boolean lazyEvaluate; - - private byte[][] tmpBuffers; - - public ASN1InputStream( - InputStream is) - { - this(is, StreamUtil.findLimit(is)); - } - - /** - * Create an ASN1InputStream based on the input byte array. The length of DER objects in - * the stream is automatically limited to the length of the input array. - * - * @param input array containing ASN.1 encoded data. - */ - public ASN1InputStream( - byte[] input) - { - this(new ByteArrayInputStream(input), input.length); - } - - /** - * Create an ASN1InputStream based on the input byte array. The length of DER objects in - * the stream is automatically limited to the length of the input array. - * - * @param input array containing ASN.1 encoded data. - * @param lazyEvaluate true if parsing inside constructed objects can be delayed. - */ - public ASN1InputStream( - byte[] input, - boolean lazyEvaluate) - { - this(new ByteArrayInputStream(input), input.length, lazyEvaluate); - } - - /** - * Create an ASN1InputStream where no DER object will be longer than limit. - * - * @param input stream containing ASN.1 encoded data. - * @param limit maximum size of a DER encoded object. - */ - public ASN1InputStream( - InputStream input, - int limit) - { - this(input, limit, false); - } - - /** - * Create an ASN1InputStream where no DER object will be longer than limit, and constructed - * objects such as sequences will be parsed lazily. - * - * @param input stream containing ASN.1 encoded data. - * @param lazyEvaluate true if parsing inside constructed objects can be delayed. - */ - public ASN1InputStream( - InputStream input, - boolean lazyEvaluate) - { - this(input, StreamUtil.findLimit(input), lazyEvaluate); - } - - /** - * Create an ASN1InputStream where no DER object will be longer than limit, and constructed - * objects such as sequences will be parsed lazily. - * - * @param input stream containing ASN.1 encoded data. - * @param limit maximum size of a DER encoded object. - * @param lazyEvaluate true if parsing inside constructed objects can be delayed. - */ - public ASN1InputStream( - InputStream input, - int limit, - boolean lazyEvaluate) - { - super(input); - this.limit = limit; - this.lazyEvaluate = lazyEvaluate; - this.tmpBuffers = new byte[11][]; - } - - int getLimit() - { - return limit; - } - - protected int readLength() - throws IOException - { - return readLength(this, limit); - } - - protected void readFully( - byte[] bytes) - throws IOException - { - if (Streams.readFully(this, bytes) != bytes.length) - { - throw new EOFException("EOF encountered in middle of object"); - } - } - - /** - * build an object given its tag and the number of bytes to construct it from. - */ - protected ASN1Primitive buildObject( - int tag, - int tagNo, - int length) - throws IOException - { - boolean isConstructed = (tag & CONSTRUCTED) != 0; - - DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length); - - if ((tag & APPLICATION) != 0) - { - return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); - } - - if ((tag & TAGGED) != 0) - { - return new ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo); - } - - if (isConstructed) - { - // TODO There are other tags that may be constructed (e.g. BIT_STRING) - switch (tagNo) - { - case OCTET_STRING: - // - // yes, people actually do this... - // - ASN1EncodableVector v = buildDEREncodableVector(defIn); - ASN1OctetString[] strings = new ASN1OctetString[v.size()]; - - for (int i = 0; i != strings.length; i++) - { - strings[i] = (ASN1OctetString)v.get(i); - } - - return new BEROctetString(strings); - case SEQUENCE: - if (lazyEvaluate) - { - return new LazyEncodedSequence(defIn.toByteArray()); - } - else - { - return DERFactory.createSequence(buildDEREncodableVector(defIn)); - } - case SET: - return DERFactory.createSet(buildDEREncodableVector(defIn)); - case EXTERNAL: - return new DERExternal(buildDEREncodableVector(defIn)); - default: - throw new IOException("unknown tag " + tagNo + " encountered"); - } - } - - return createPrimitiveDERObject(tagNo, defIn, tmpBuffers); - } - - ASN1EncodableVector buildEncodableVector() - throws IOException - { - ASN1EncodableVector v = new ASN1EncodableVector(); - ASN1Primitive o; - - while ((o = readObject()) != null) - { - v.add(o); - } - - return v; - } - - ASN1EncodableVector buildDEREncodableVector( - DefiniteLengthInputStream dIn) throws IOException - { - return new ASN1InputStream(dIn).buildEncodableVector(); - } - - public ASN1Primitive readObject() - throws IOException - { - int tag = read(); - if (tag <= 0) - { - if (tag == 0) - { - throw new IOException("unexpected end-of-contents marker"); - } - - return null; - } - - // - // calculate tag number - // - int tagNo = readTagNumber(this, tag); - - boolean isConstructed = (tag & CONSTRUCTED) != 0; - - // - // calculate length - // - int length = readLength(); - - if (length < 0) // indefinite length method - { - if (!isConstructed) - { - throw new IOException("indefinite length primitive encoding encountered"); - } - - IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit); - ASN1StreamParser sp = new ASN1StreamParser(indIn, limit); - - if ((tag & APPLICATION) != 0) - { - return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject(); - } - - if ((tag & TAGGED) != 0) - { - return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject(); - } - - // TODO There are other tags that may be constructed (e.g. BIT_STRING) - switch (tagNo) - { - case OCTET_STRING: - return new BEROctetStringParser(sp).getLoadedObject(); - case SEQUENCE: - return new BERSequenceParser(sp).getLoadedObject(); - case SET: - return new BERSetParser(sp).getLoadedObject(); - case EXTERNAL: - return new DERExternalParser(sp).getLoadedObject(); - default: - throw new IOException("unknown BER object encountered"); - } - } - else - { - try - { - return buildObject(tag, tagNo, length); - } - catch (IllegalArgumentException e) - { - throw new ASN1Exception("corrupted stream detected", e); - } - } - } - - static int readTagNumber(InputStream s, int tag) - throws IOException - { - int tagNo = tag & 0x1f; - - // - // with tagged object tag number is bottom 5 bits, or stored at the start of the content - // - if (tagNo == 0x1f) - { - tagNo = 0; - - int b = s.read(); - - // X.690-0207 8.1.2.4.2 - // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." - if ((b & 0x7f) == 0) // Note: -1 will pass - { - throw new IOException("corrupted stream - invalid high tag number found"); - } - - while ((b >= 0) && ((b & 0x80) != 0)) - { - tagNo |= (b & 0x7f); - tagNo <<= 7; - b = s.read(); - } - - if (b < 0) - { - throw new EOFException("EOF found inside tag value."); - } - - tagNo |= (b & 0x7f); - } - - return tagNo; - } - - static int readLength(InputStream s, int limit) - throws IOException - { - int length = s.read(); - if (length < 0) - { - throw new EOFException("EOF found when length expected"); - } - - if (length == 0x80) - { - return -1; // indefinite-length encoding - } - - if (length > 127) - { - int size = length & 0x7f; - - // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here - if (size > 4) - { - throw new IOException("DER length more than 4 bytes: " + size); - } - - length = 0; - for (int i = 0; i < size; i++) - { - int next = s.read(); - - if (next < 0) - { - throw new EOFException("EOF found reading length"); - } - - length = (length << 8) + next; - } - - if (length < 0) - { - throw new IOException("corrupted stream - negative length found"); - } - - if (length >= limit) // after all we must have read at least 1 byte - { - throw new IOException("corrupted stream - out of bounds length found"); - } - } - - return length; - } - - private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers) - throws IOException - { - int len = defIn.getRemaining(); - if (defIn.getRemaining() < tmpBuffers.length) - { - byte[] buf = tmpBuffers[len]; - - if (buf == null) - { - buf = tmpBuffers[len] = new byte[len]; - } - - Streams.readFully(defIn, buf); - - return buf; - } - else - { - return defIn.toByteArray(); - } - } - - private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn) - throws IOException - { - int len = defIn.getRemaining() / 2; - char[] buf = new char[len]; - int totalRead = 0; - while (totalRead < len) - { - int ch1 = defIn.read(); - if (ch1 < 0) - { - break; - } - int ch2 = defIn.read(); - if (ch2 < 0) - { - break; - } - buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff)); - } - - return buf; - } - - static ASN1Primitive createPrimitiveDERObject( - int tagNo, - DefiniteLengthInputStream defIn, - byte[][] tmpBuffers) - throws IOException - { - switch (tagNo) - { - case BIT_STRING: - return DERBitString.fromInputStream(defIn.getRemaining(), defIn); - case BMP_STRING: - return new DERBMPString(getBMPCharBuffer(defIn)); - case BOOLEAN: - return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers)); - case ENUMERATED: - return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers)); - case GENERALIZED_TIME: - return new ASN1GeneralizedTime(defIn.toByteArray()); - case GENERAL_STRING: - return new DERGeneralString(defIn.toByteArray()); - case IA5_STRING: - return new DERIA5String(defIn.toByteArray()); - case INTEGER: - return new ASN1Integer(defIn.toByteArray(), false); - case NULL: - return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?) - case NUMERIC_STRING: - return new DERNumericString(defIn.toByteArray()); - case OBJECT_IDENTIFIER: - return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers)); - case OCTET_STRING: - return new DEROctetString(defIn.toByteArray()); - case PRINTABLE_STRING: - return new DERPrintableString(defIn.toByteArray()); - case T61_STRING: - return new DERT61String(defIn.toByteArray()); - case UNIVERSAL_STRING: - return new DERUniversalString(defIn.toByteArray()); - case UTC_TIME: - return new ASN1UTCTime(defIn.toByteArray()); - case UTF8_STRING: - return new DERUTF8String(defIn.toByteArray()); - case VISIBLE_STRING: - return new DERVisibleString(defIn.toByteArray()); - default: - throw new IOException("unknown tag " + tagNo + " encountered"); - } - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1StreamParser.java b/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1StreamParser.java deleted file mode 100644 index 8ef5f3e6..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/asn1/ASN1StreamParser.java +++ /dev/null @@ -1,247 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -public class ASN1StreamParser -{ - private InputStream _in; - private int _limit; - private byte[][] tmpBuffers; - - public ASN1StreamParser( - InputStream in) - { - this(in, StreamUtil.findLimit(in)); - } - - public ASN1StreamParser( - InputStream in, - int limit) - { - this._in = in; - this._limit = limit; - - this.tmpBuffers = new byte[11][]; - } - - public ASN1StreamParser( - byte[] encoding) - { - this(new ByteArrayInputStream(encoding), encoding.length); - } - - ASN1Encodable readIndef(int tagValue) throws IOException - { - // Note: INDEF => CONSTRUCTED - - // TODO There are other tags that may be constructed (e.g. BIT_STRING) - switch (tagValue) - { - case BERTags.EXTERNAL: - return new DERExternalParser(this); - case BERTags.OCTET_STRING: - return new BEROctetStringParser(this); - case BERTags.SEQUENCE: - return new BERSequenceParser(this); - case BERTags.SET: - return new BERSetParser(this); - default: - throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue)); - } - } - - ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException - { - if (_in instanceof IndefiniteLengthInputStream) - { - if (!constructed) - { - throw new IOException("indefinite length primitive encoding encountered"); - } - - return readIndef(tag); - } - - if (constructed) - { - switch (tag) - { - case BERTags.SET: - return new DERSetParser(this); - case BERTags.SEQUENCE: - return new DERSequenceParser(this); - case BERTags.OCTET_STRING: - return new BEROctetStringParser(this); - } - } - else - { - switch (tag) - { - case BERTags.SET: - throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)"); - case BERTags.SEQUENCE: - throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)"); - case BERTags.OCTET_STRING: - return new DEROctetStringParser((DefiniteLengthInputStream)_in); - } - } - - // TODO ASN1Exception - throw new RuntimeException("implicit tagging not implemented"); - } - - ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException - { - if (!constructed) - { - // Note: !CONSTRUCTED => IMPLICIT - DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in; - return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray())); - } - - ASN1EncodableVector v = readVector(); - - if (_in instanceof IndefiniteLengthInputStream) - { - return v.size() == 1 - ? new BERTaggedObject(true, tag, v.get(0)) - : new BERTaggedObject(false, tag, BERFactory.createSequence(v)); - } - - return v.size() == 1 - ? new DERTaggedObject(true, tag, v.get(0)) - : new DERTaggedObject(false, tag, DERFactory.createSequence(v)); - } - - public ASN1Encodable readObject() - throws IOException - { - int tag = _in.read(); - if (tag == -1) - { - return null; - } - - // - // turn of looking for "00" while we resolve the tag - // - set00Check(false); - - // - // calculate tag number - // - int tagNo = ASN1InputStream.readTagNumber(_in, tag); - - boolean isConstructed = (tag & BERTags.CONSTRUCTED) != 0; - - // - // calculate length - // - int length = ASN1InputStream.readLength(_in, _limit); - - if (length < 0) // indefinite length method - { - if (!isConstructed) - { - throw new IOException("indefinite length primitive encoding encountered"); - } - - IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit); - ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit); - - if ((tag & BERTags.APPLICATION) != 0) - { - return new BERApplicationSpecificParser(tagNo, sp); - } - - if ((tag & BERTags.TAGGED) != 0) - { - return new BERTaggedObjectParser(true, tagNo, sp); - } - - return sp.readIndef(tagNo); - } - else - { - DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length); - - if ((tag & BERTags.APPLICATION) != 0) - { - return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); - } - - if ((tag & BERTags.TAGGED) != 0) - { - return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn)); - } - - if (isConstructed) - { - // TODO There are other tags that may be constructed (e.g. BIT_STRING) - switch (tagNo) - { - case BERTags.OCTET_STRING: - // - // yes, people actually do this... - // - return new BEROctetStringParser(new ASN1StreamParser(defIn)); - case BERTags.SEQUENCE: - return new DERSequenceParser(new ASN1StreamParser(defIn)); - case BERTags.SET: - return new DERSetParser(new ASN1StreamParser(defIn)); - case BERTags.EXTERNAL: - return new DERExternalParser(new ASN1StreamParser(defIn)); - default: - throw new IOException("unknown tag " + tagNo + " encountered"); - } - } - - // Some primitive encodings can be handled by parsers too... - switch (tagNo) - { - case BERTags.OCTET_STRING: - return new DEROctetStringParser(defIn); - } - - try - { - return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers); - } - catch (IllegalArgumentException e) - { - throw new ASN1Exception("corrupted stream detected", e); - } - } - } - - private void set00Check(boolean enabled) - { - if (_in instanceof IndefiniteLengthInputStream) - { - ((IndefiniteLengthInputStream)_in).setEofOn00(enabled); - } - } - - ASN1EncodableVector readVector() throws IOException - { - ASN1EncodableVector v = new ASN1EncodableVector(); - - ASN1Encodable obj; - while ((obj = readObject()) != null) - { - if (obj instanceof InMemoryRepresentable) - { - v.add(((InMemoryRepresentable)obj).getLoadedObject()); - } - else - { - v.add(obj.toASN1Primitive()); - } - } - - return v; - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/asn1/DERApplicationSpecific.java b/core/src/main/jdk1.1/org/bouncycastle/asn1/DERApplicationSpecific.java deleted file mode 100644 index 2726d6e9..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/asn1/DERApplicationSpecific.java +++ /dev/null @@ -1,276 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.bouncycastle.util.Arrays; - -/** - * Base class for an application specific object - */ -public class DERApplicationSpecific - extends ASN1Primitive -{ - private boolean isConstructed; - private int tag; - private byte[] octets; - - DERApplicationSpecific( - boolean isConstructed, - int tag, - byte[] octets) - { - this.isConstructed = isConstructed; - this.tag = tag; - this.octets = octets; - } - - public DERApplicationSpecific( - int tag, - byte[] octets) - { - this(false, tag, octets); - } - - public DERApplicationSpecific( - int tag, - ASN1Encodable object) - throws IOException - { - this(true, tag, object); - } - - public DERApplicationSpecific( - boolean explicit, - int tag, - ASN1Encodable object) - throws IOException - { - ASN1Primitive primitive = object.toASN1Primitive(); - - byte[] data = primitive.getEncoded(ASN1Encoding.DER); - - this.isConstructed = explicit || (primitive instanceof ASN1Set || primitive instanceof ASN1Sequence); - this.tag = tag; - - if (explicit) - { - this.octets = data; - } - else - { - int lenBytes = getLengthOfHeader(data); - byte[] tmp = new byte[data.length - lenBytes]; - System.arraycopy(data, lenBytes, tmp, 0, tmp.length); - this.octets = tmp; - } - } - - public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec) - { - this.tag = tagNo; - this.isConstructed = true; - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - for (int i = 0; i != vec.size(); i++) - { - try - { - bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER)); - } - catch (IOException e) - { - throw new ASN1ParsingException("malformed object: " + e, e); - } - } - this.octets = bOut.toByteArray(); - } - - public static DERApplicationSpecific getInstance(Object obj) - { - if (obj == null || obj instanceof DERApplicationSpecific) - { - return (DERApplicationSpecific)obj; - } - else if (obj instanceof byte[]) - { - try - { - return DERApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj)); - } - catch (IOException e) - { - throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage()); - } - } - else if (obj instanceof ASN1Encodable) - { - ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); - - if (primitive instanceof ASN1Sequence) - { - return (DERApplicationSpecific)primitive; - } - } - - throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); - } - - private int getLengthOfHeader(byte[] data) - { - int length = data[1] & 0xff; // TODO: assumes 1 byte tag - - if (length == 0x80) - { - return 2; // indefinite-length encoding - } - - if (length > 127) - { - int size = length & 0x7f; - - // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here - if (size > 4) - { - throw new IllegalStateException("DER length more than 4 bytes: " + size); - } - - return size + 2; - } - - return 2; - } - - public boolean isConstructed() - { - return isConstructed; - } - - public byte[] getContents() - { - return octets; - } - - public int getApplicationTag() - { - return tag; - } - - /** - * Return the enclosed object assuming explicit tagging. - * - * @return the resulting object - * @throws IOException if reconstruction fails. - */ - public ASN1Primitive getObject() - throws IOException - { - return new ASN1InputStream(getContents()).readObject(); - } - - /** - * Return the enclosed object assuming implicit tagging. - * - * @param derTagNo the type tag that should be applied to the object's contents. - * @return the resulting object - * @throws IOException if reconstruction fails. - */ - public ASN1Primitive getObject(int derTagNo) - throws IOException - { - if (derTagNo >= 0x1f) - { - throw new IOException("unsupported tag number"); - } - - byte[] orig = this.getEncoded(); - byte[] tmp = replaceTagNumber(derTagNo, orig); - - if ((orig[0] & BERTags.CONSTRUCTED) != 0) - { - tmp[0] |= BERTags.CONSTRUCTED; - } - - return new ASN1InputStream(tmp).readObject(); - } - - int encodedLength() - throws IOException - { - return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length; - } - - /* (non-Javadoc) - * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream) - */ - void encode(ASN1OutputStream out) throws IOException - { - int classBits = BERTags.APPLICATION; - if (isConstructed) - { - classBits |= BERTags.CONSTRUCTED; - } - - out.writeEncoded(classBits, tag, octets); - } - - boolean asn1Equals( - ASN1Primitive o) - { - if (!(o instanceof DERApplicationSpecific)) - { - return false; - } - - DERApplicationSpecific other = (DERApplicationSpecific)o; - - return isConstructed == other.isConstructed - && tag == other.tag - && Arrays.areEqual(octets, other.octets); - } - - public int hashCode() - { - return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets); - } - - private byte[] replaceTagNumber(int newTag, byte[] input) - throws IOException - { - int tagNo = input[0] & 0x1f; - int index = 1; - // - // with tagged object tag number is bottom 5 bits, or stored at the start of the content - // - if (tagNo == 0x1f) - { - tagNo = 0; - - int b = input[index++] & 0xff; - - // X.690-0207 8.1.2.4.2 - // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." - if ((b & 0x7f) == 0) // Note: -1 will pass - { - throw new ASN1ParsingException("corrupted stream - invalid high tag number found"); - } - - while ((b >= 0) && ((b & 0x80) != 0)) - { - tagNo |= (b & 0x7f); - tagNo <<= 7; - b = input[index++] & 0xff; - } - - tagNo |= (b & 0x7f); - } - - byte[] tmp = new byte[input.length - index + 1]; - - System.arraycopy(input, index, tmp, 1, tmp.length - 1); - - tmp[0] = (byte)newTag; - - return tmp; - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/asn1/x500/style/BCStyle.java b/core/src/main/jdk1.1/org/bouncycastle/asn1/x500/style/BCStyle.java deleted file mode 100644 index 15e3c2a7..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/asn1/x500/style/BCStyle.java +++ /dev/null @@ -1,481 +0,0 @@ -package org.bouncycastle.asn1.x500.style; - -import java.io.IOException; -import java.util.Enumeration; -import java.util.Hashtable; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1GeneralizedTime; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.DERPrintableString; -import org.bouncycastle.asn1.DERUTF8String; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x500.AttributeTypeAndValue; -import org.bouncycastle.asn1.x500.RDN; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x500.X500NameStyle; -import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; - -public class BCStyle - implements X500NameStyle -{ - /** - * country code - StringType(SIZE(2)) - */ - public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6"); - - /** - * organization - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10"); - - /** - * organizational unit name - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11"); - - /** - * Title - */ - public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12"); - - /** - * common name - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3"); - - /** - * device serial number name - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5"); - - /** - * street - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9"); - - /** - * device serial number name - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier SERIALNUMBER = SN; - - /** - * locality name - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7"); - - /** - * state, or province name - StringType(SIZE(1..64)) - */ - public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8"); - - /** - * Naming attributes of type X520name - */ - public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4"); - public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42"); - public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43"); - public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44"); - public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45"); - - /** - * businessCategory - DirectoryString(SIZE(1..128) - */ - public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier( - "2.5.4.15"); - - /** - * postalCode - DirectoryString(SIZE(1..40) - */ - public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier( - "2.5.4.17"); - - /** - * dnQualifier - DirectoryString(SIZE(1..64) - */ - public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier( - "2.5.4.46"); - - /** - * RFC 3039 Pseudonym - DirectoryString(SIZE(1..64) - */ - public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier( - "2.5.4.65"); - - - /** - * RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z - */ - public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier( - "1.3.6.1.5.5.7.9.1"); - - /** - * RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128) - */ - public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier( - "1.3.6.1.5.5.7.9.2"); - - /** - * RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f" - */ - public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier( - "1.3.6.1.5.5.7.9.3"); - - /** - * RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166 - * codes only - */ - public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier( - "1.3.6.1.5.5.7.9.4"); - - /** - * RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166 - * codes only - */ - public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier( - "1.3.6.1.5.5.7.9.5"); - - - /** - * ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64) - */ - public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14"); - - /** - * RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF - * DirectoryString(SIZE(1..30)) - */ - public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16"); - - /** - * RFC 2256 dmdName - */ - public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54"); - - /** - * id-at-telephoneNumber - */ - public static final ASN1ObjectIdentifier TELEPHONE_NUMBER = X509ObjectIdentifiers.id_at_telephoneNumber; - - /** - * id-at-name - */ - public static final ASN1ObjectIdentifier NAME = X509ObjectIdentifiers.id_at_name; - - /** - * Email address (RSA PKCS#9 extension) - IA5String. - * <p>Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here. - */ - public static final ASN1ObjectIdentifier EmailAddress = PKCSObjectIdentifiers.pkcs_9_at_emailAddress; - - /** - * more from PKCS#9 - */ - public static final ASN1ObjectIdentifier UnstructuredName = PKCSObjectIdentifiers.pkcs_9_at_unstructuredName; - public static final ASN1ObjectIdentifier UnstructuredAddress = PKCSObjectIdentifiers.pkcs_9_at_unstructuredAddress; - - /** - * email address in Verisign certificates - */ - public static final ASN1ObjectIdentifier E = EmailAddress; - - /* - * others... - */ - public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25"); - - /** - * LDAP User id. - */ - public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); - - /** - * default look up table translating OID values into their common symbols following - * the convention in RFC 2253 with a few extras - */ - private static final Hashtable DefaultSymbols = new Hashtable(); - - /** - * look up table translating common symbols into their OIDS. - */ - private static final Hashtable DefaultLookUp = new Hashtable(); - - static - { - DefaultSymbols.put(C, "C"); - DefaultSymbols.put(O, "O"); - DefaultSymbols.put(T, "T"); - DefaultSymbols.put(OU, "OU"); - DefaultSymbols.put(CN, "CN"); - DefaultSymbols.put(L, "L"); - DefaultSymbols.put(ST, "ST"); - DefaultSymbols.put(SN, "SERIALNUMBER"); - DefaultSymbols.put(EmailAddress, "E"); - DefaultSymbols.put(DC, "DC"); - DefaultSymbols.put(UID, "UID"); - DefaultSymbols.put(STREET, "STREET"); - DefaultSymbols.put(SURNAME, "SURNAME"); - DefaultSymbols.put(GIVENNAME, "GIVENNAME"); - DefaultSymbols.put(INITIALS, "INITIALS"); - DefaultSymbols.put(GENERATION, "GENERATION"); - DefaultSymbols.put(UnstructuredAddress, "unstructuredAddress"); - DefaultSymbols.put(UnstructuredName, "unstructuredName"); - DefaultSymbols.put(UNIQUE_IDENTIFIER, "UniqueIdentifier"); - DefaultSymbols.put(DN_QUALIFIER, "DN"); - DefaultSymbols.put(PSEUDONYM, "Pseudonym"); - DefaultSymbols.put(POSTAL_ADDRESS, "PostalAddress"); - DefaultSymbols.put(NAME_AT_BIRTH, "NameAtBirth"); - DefaultSymbols.put(COUNTRY_OF_CITIZENSHIP, "CountryOfCitizenship"); - DefaultSymbols.put(COUNTRY_OF_RESIDENCE, "CountryOfResidence"); - DefaultSymbols.put(GENDER, "Gender"); - DefaultSymbols.put(PLACE_OF_BIRTH, "PlaceOfBirth"); - DefaultSymbols.put(DATE_OF_BIRTH, "DateOfBirth"); - DefaultSymbols.put(POSTAL_CODE, "PostalCode"); - DefaultSymbols.put(BUSINESS_CATEGORY, "BusinessCategory"); - DefaultSymbols.put(TELEPHONE_NUMBER, "TelephoneNumber"); - DefaultSymbols.put(NAME, "Name"); - - DefaultLookUp.put("c", C); - DefaultLookUp.put("o", O); - DefaultLookUp.put("t", T); - DefaultLookUp.put("ou", OU); - DefaultLookUp.put("cn", CN); - DefaultLookUp.put("l", L); - DefaultLookUp.put("st", ST); - DefaultLookUp.put("sn", SN); - DefaultLookUp.put("serialnumber", SN); - DefaultLookUp.put("street", STREET); - DefaultLookUp.put("emailaddress", E); - DefaultLookUp.put("dc", DC); - DefaultLookUp.put("e", E); - DefaultLookUp.put("uid", UID); - DefaultLookUp.put("surname", SURNAME); - DefaultLookUp.put("givenname", GIVENNAME); - DefaultLookUp.put("initials", INITIALS); - DefaultLookUp.put("generation", GENERATION); - DefaultLookUp.put("unstructuredaddress", UnstructuredAddress); - DefaultLookUp.put("unstructuredname", UnstructuredName); - DefaultLookUp.put("uniqueidentifier", UNIQUE_IDENTIFIER); - DefaultLookUp.put("dn", DN_QUALIFIER); - DefaultLookUp.put("pseudonym", PSEUDONYM); - DefaultLookUp.put("postaladdress", POSTAL_ADDRESS); - DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH); - DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP); - DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE); - DefaultLookUp.put("gender", GENDER); - DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH); - DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH); - DefaultLookUp.put("postalcode", POSTAL_CODE); - DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY); - DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER); - DefaultLookUp.put("name", NAME); - } - - /** - * Singleton instance. - */ - public static final X500NameStyle INSTANCE = new BCStyle(); - - protected Hashtable defaultLookUp; - protected Hashtable defaultSymbols; - - protected BCStyle() - { - defaultSymbols = copyHashTable(DefaultSymbols); - defaultLookUp = copyHashTable(DefaultLookUp); - } - - public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value) - { - if (value.length() != 0 && value.charAt(0) == '#') - { - try - { - return IETFUtils.valueFromHexString(value, 1); - } - catch (IOException e) - { - throw new RuntimeException("can't recode value for oid " + oid.getId()); - } - } - else - { - if (value.length() != 0 && value.charAt(0) == '\\') - { - value = value.substring(1); - } - if (oid.equals(EmailAddress) || oid.equals(DC)) - { - return new DERIA5String(value); - } - else if (oid.equals(DATE_OF_BIRTH)) // accept time string as well as # (for compatibility) - { - return new ASN1GeneralizedTime(value); - } - else if (oid.equals(C) || oid.equals(SN) || oid.equals(DN_QUALIFIER) - || oid.equals(TELEPHONE_NUMBER)) - { - return new DERPrintableString(value); - } - } - - return new DERUTF8String(value); - } - - public String oidToDisplayName(ASN1ObjectIdentifier oid) - { - return (String)DefaultSymbols.get(oid); - } - - public String[] oidToAttrNames(ASN1ObjectIdentifier oid) - { - return IETFUtils.findAttrNamesForOID(oid, defaultLookUp); - } - - public ASN1ObjectIdentifier attrNameToOID(String attrName) - { - return IETFUtils.decodeAttrName(attrName, defaultLookUp); - } - - public boolean areEqual(X500Name name1, X500Name name2) - { - RDN[] rdns1 = name1.getRDNs(); - RDN[] rdns2 = name2.getRDNs(); - - if (rdns1.length != rdns2.length) - { - return false; - } - - boolean reverse = false; - - if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null) - { - reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward - } - - for (int i = 0; i != rdns1.length; i++) - { - if (!foundMatch(reverse, rdns1[i], rdns2)) - { - return false; - } - } - - return true; - } - - private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs) - { - if (reverse) - { - for (int i = possRDNs.length - 1; i >= 0; i--) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - else - { - for (int i = 0; i != possRDNs.length; i++) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - - return false; - } - - protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) - { - return IETFUtils.rDNAreEqual(rdn1, rdn2); - } - - public RDN[] fromString(String dirName) - { - return IETFUtils.rDNsFromString(dirName, this); - } - - public int calculateHashCode(X500Name name) - { - int hashCodeValue = 0; - RDN[] rdns = name.getRDNs(); - - // this needs to be order independent, like equals - for (int i = 0; i != rdns.length; i++) - { - if (rdns[i].isMultiValued()) - { - AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); - - for (int j = 0; j != atv.length; j++) - { - hashCodeValue ^= atv[j].getType().hashCode(); - hashCodeValue ^= calcHashCode(atv[j].getValue()); - } - } - else - { - hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); - hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); - } - } - - return hashCodeValue; - } - - private int calcHashCode(ASN1Encodable enc) - { - String value = IETFUtils.valueToString(enc); - - value = IETFUtils.canonicalize(value); - - return value.hashCode(); - } - - public String toString(X500Name name) - { - StringBuffer buf = new StringBuffer(); - boolean first = true; - - RDN[] rdns = name.getRDNs(); - - for (int i = 0; i < rdns.length; i++) - { - if (first) - { - first = false; - } - else - { - buf.append(','); - } - - IETFUtils.appendRDN(buf, rdns[i], defaultSymbols); - } - - return buf.toString(); - } - - private static Hashtable copyHashTable(Hashtable paramsMap) - { - Hashtable newTable = new Hashtable(); - - Enumeration keys = paramsMap.keys(); - while (keys.hasMoreElements()) - { - Object key = keys.nextElement(); - newTable.put(key, paramsMap.get(key)); - } - - return newTable; - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/core/src/main/jdk1.1/org/bouncycastle/asn1/x500/style/RFC4519Style.java deleted file mode 100644 index e5ff6a11..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/asn1/x500/style/RFC4519Style.java +++ /dev/null @@ -1,380 +0,0 @@ -package org.bouncycastle.asn1.x500.style; - -import java.io.IOException; -import java.util.Enumeration; -import java.util.Hashtable; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.DERPrintableString; -import org.bouncycastle.asn1.DERUTF8String; -import org.bouncycastle.asn1.x500.AttributeTypeAndValue; -import org.bouncycastle.asn1.x500.RDN; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x500.X500NameStyle; - -public class RFC4519Style - implements X500NameStyle -{ - public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15"); - public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6"); - public static final ASN1ObjectIdentifier cn = new ASN1ObjectIdentifier("2.5.4.3"); - public static final ASN1ObjectIdentifier dc = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25"); - public static final ASN1ObjectIdentifier description = new ASN1ObjectIdentifier("2.5.4.13"); - public static final ASN1ObjectIdentifier destinationIndicator = new ASN1ObjectIdentifier("2.5.4.27"); - public static final ASN1ObjectIdentifier distinguishedName = new ASN1ObjectIdentifier("2.5.4.49"); - public static final ASN1ObjectIdentifier dnQualifier = new ASN1ObjectIdentifier("2.5.4.46"); - public static final ASN1ObjectIdentifier enhancedSearchGuide = new ASN1ObjectIdentifier("2.5.4.47"); - public static final ASN1ObjectIdentifier facsimileTelephoneNumber = new ASN1ObjectIdentifier("2.5.4.23"); - public static final ASN1ObjectIdentifier generationQualifier = new ASN1ObjectIdentifier("2.5.4.44"); - public static final ASN1ObjectIdentifier givenName = new ASN1ObjectIdentifier("2.5.4.42"); - public static final ASN1ObjectIdentifier houseIdentifier = new ASN1ObjectIdentifier("2.5.4.51"); - public static final ASN1ObjectIdentifier initials = new ASN1ObjectIdentifier("2.5.4.43"); - public static final ASN1ObjectIdentifier internationalISDNNumber = new ASN1ObjectIdentifier("2.5.4.25"); - public static final ASN1ObjectIdentifier l = new ASN1ObjectIdentifier("2.5.4.7"); - public static final ASN1ObjectIdentifier member = new ASN1ObjectIdentifier("2.5.4.31"); - public static final ASN1ObjectIdentifier name = new ASN1ObjectIdentifier("2.5.4.41"); - public static final ASN1ObjectIdentifier o = new ASN1ObjectIdentifier("2.5.4.10"); - public static final ASN1ObjectIdentifier ou = new ASN1ObjectIdentifier("2.5.4.11"); - public static final ASN1ObjectIdentifier owner = new ASN1ObjectIdentifier("2.5.4.32"); - public static final ASN1ObjectIdentifier physicalDeliveryOfficeName = new ASN1ObjectIdentifier("2.5.4.19"); - public static final ASN1ObjectIdentifier postalAddress = new ASN1ObjectIdentifier("2.5.4.16"); - public static final ASN1ObjectIdentifier postalCode = new ASN1ObjectIdentifier("2.5.4.17"); - public static final ASN1ObjectIdentifier postOfficeBox = new ASN1ObjectIdentifier("2.5.4.18"); - public static final ASN1ObjectIdentifier preferredDeliveryMethod = new ASN1ObjectIdentifier("2.5.4.28"); - public static final ASN1ObjectIdentifier registeredAddress = new ASN1ObjectIdentifier("2.5.4.26"); - public static final ASN1ObjectIdentifier roleOccupant = new ASN1ObjectIdentifier("2.5.4.33"); - public static final ASN1ObjectIdentifier searchGuide = new ASN1ObjectIdentifier("2.5.4.14"); - public static final ASN1ObjectIdentifier seeAlso = new ASN1ObjectIdentifier("2.5.4.34"); - public static final ASN1ObjectIdentifier serialNumber = new ASN1ObjectIdentifier("2.5.4.5"); - public static final ASN1ObjectIdentifier sn = new ASN1ObjectIdentifier("2.5.4.4"); - public static final ASN1ObjectIdentifier st = new ASN1ObjectIdentifier("2.5.4.8"); - public static final ASN1ObjectIdentifier street = new ASN1ObjectIdentifier("2.5.4.9"); - public static final ASN1ObjectIdentifier telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20"); - public static final ASN1ObjectIdentifier teletexTerminalIdentifier = new ASN1ObjectIdentifier("2.5.4.22"); - public static final ASN1ObjectIdentifier telexNumber = new ASN1ObjectIdentifier("2.5.4.21"); - public static final ASN1ObjectIdentifier title = new ASN1ObjectIdentifier("2.5.4.12"); - public static final ASN1ObjectIdentifier uid = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); - public static final ASN1ObjectIdentifier uniqueMember = new ASN1ObjectIdentifier("2.5.4.50"); - public static final ASN1ObjectIdentifier userPassword = new ASN1ObjectIdentifier("2.5.4.35"); - public static final ASN1ObjectIdentifier x121Address = new ASN1ObjectIdentifier("2.5.4.24"); - public static final ASN1ObjectIdentifier x500UniqueIdentifier = new ASN1ObjectIdentifier("2.5.4.45"); - - /** - * default look up table translating OID values into their common symbols following - * the convention in RFC 2253 with a few extras - */ - private static final Hashtable DefaultSymbols = new Hashtable(); - - /** - * look up table translating common symbols into their OIDS. - */ - private static final Hashtable DefaultLookUp = new Hashtable(); - - static - { - DefaultSymbols.put(businessCategory, "businessCategory"); - DefaultSymbols.put(c, "c"); - DefaultSymbols.put(cn, "cn"); - DefaultSymbols.put(dc, "dc"); - DefaultSymbols.put(description, "description"); - DefaultSymbols.put(destinationIndicator, "destinationIndicator"); - DefaultSymbols.put(distinguishedName, "distinguishedName"); - DefaultSymbols.put(dnQualifier, "dnQualifier"); - DefaultSymbols.put(enhancedSearchGuide, "enhancedSearchGuide"); - DefaultSymbols.put(facsimileTelephoneNumber, "facsimileTelephoneNumber"); - DefaultSymbols.put(generationQualifier, "generationQualifier"); - DefaultSymbols.put(givenName, "givenName"); - DefaultSymbols.put(houseIdentifier, "houseIdentifier"); - DefaultSymbols.put(initials, "initials"); - DefaultSymbols.put(internationalISDNNumber, "internationalISDNNumber"); - DefaultSymbols.put(l, "l"); - DefaultSymbols.put(member, "member"); - DefaultSymbols.put(name, "name"); - DefaultSymbols.put(o, "o"); - DefaultSymbols.put(ou, "ou"); - DefaultSymbols.put(owner, "owner"); - DefaultSymbols.put(physicalDeliveryOfficeName, "physicalDeliveryOfficeName"); - DefaultSymbols.put(postalAddress, "postalAddress"); - DefaultSymbols.put(postalCode, "postalCode"); - DefaultSymbols.put(postOfficeBox, "postOfficeBox"); - DefaultSymbols.put(preferredDeliveryMethod, "preferredDeliveryMethod"); - DefaultSymbols.put(registeredAddress, "registeredAddress"); - DefaultSymbols.put(roleOccupant, "roleOccupant"); - DefaultSymbols.put(searchGuide, "searchGuide"); - DefaultSymbols.put(seeAlso, "seeAlso"); - DefaultSymbols.put(serialNumber, "serialNumber"); - DefaultSymbols.put(sn, "sn"); - DefaultSymbols.put(st, "st"); - DefaultSymbols.put(street, "street"); - DefaultSymbols.put(telephoneNumber, "telephoneNumber"); - DefaultSymbols.put(teletexTerminalIdentifier, "teletexTerminalIdentifier"); - DefaultSymbols.put(telexNumber, "telexNumber"); - DefaultSymbols.put(title, "title"); - DefaultSymbols.put(uid, "uid"); - DefaultSymbols.put(uniqueMember, "uniqueMember"); - DefaultSymbols.put(userPassword, "userPassword"); - DefaultSymbols.put(x121Address, "x121Address"); - DefaultSymbols.put(x500UniqueIdentifier, "x500UniqueIdentifier"); - - DefaultLookUp.put("businesscategory", businessCategory); - DefaultLookUp.put("c", c); - DefaultLookUp.put("cn", cn); - DefaultLookUp.put("dc", dc); - DefaultLookUp.put("description", description); - DefaultLookUp.put("destinationindicator", destinationIndicator); - DefaultLookUp.put("distinguishedname", distinguishedName); - DefaultLookUp.put("dnqualifier", dnQualifier); - DefaultLookUp.put("enhancedsearchguide", enhancedSearchGuide); - DefaultLookUp.put("facsimiletelephonenumber", facsimileTelephoneNumber); - DefaultLookUp.put("generationqualifier", generationQualifier); - DefaultLookUp.put("givenname", givenName); - DefaultLookUp.put("houseidentifier", houseIdentifier); - DefaultLookUp.put("initials", initials); - DefaultLookUp.put("internationalisdnnumber", internationalISDNNumber); - DefaultLookUp.put("l", l); - DefaultLookUp.put("member", member); - DefaultLookUp.put("name", name); - DefaultLookUp.put("o", o); - DefaultLookUp.put("ou", ou); - DefaultLookUp.put("owner", owner); - DefaultLookUp.put("physicaldeliveryofficename", physicalDeliveryOfficeName); - DefaultLookUp.put("postaladdress", postalAddress); - DefaultLookUp.put("postalcode", postalCode); - DefaultLookUp.put("postofficebox", postOfficeBox); - DefaultLookUp.put("preferreddeliverymethod", preferredDeliveryMethod); - DefaultLookUp.put("registeredaddress", registeredAddress); - DefaultLookUp.put("roleoccupant", roleOccupant); - DefaultLookUp.put("searchguide", searchGuide); - DefaultLookUp.put("seealso", seeAlso); - DefaultLookUp.put("serialnumber", serialNumber); - DefaultLookUp.put("sn", sn); - DefaultLookUp.put("st", st); - DefaultLookUp.put("street", street); - DefaultLookUp.put("telephonenumber", telephoneNumber); - DefaultLookUp.put("teletexterminalidentifier", teletexTerminalIdentifier); - DefaultLookUp.put("telexnumber", telexNumber); - DefaultLookUp.put("title", title); - DefaultLookUp.put("uid", uid); - DefaultLookUp.put("uniquemember", uniqueMember); - DefaultLookUp.put("userpassword", userPassword); - DefaultLookUp.put("x121address", x121Address); - DefaultLookUp.put("x500uniqueidentifier", x500UniqueIdentifier); - - // TODO: need to add correct matching for equality comparisons. - } - - /** - * Singleton instance. - */ - public static final X500NameStyle INSTANCE = new RFC4519Style(); - - protected Hashtable defaultLookUp; - protected Hashtable defaultSymbols; - - protected RFC4519Style() - { - defaultSymbols = copyHashTable(DefaultSymbols); - defaultLookUp = copyHashTable(DefaultLookUp); - } - - public ASN1Encodable stringToValue(ASN1ObjectIdentifier oid, String value) - { - if (value.length() != 0 && value.charAt(0) == '#') - { - try - { - return IETFUtils.valueFromHexString(value, 1); - } - catch (IOException e) - { - throw new RuntimeException("can't recode value for oid " + oid.getId()); - } - } - else - { - if (value.length() != 0 && value.charAt(0) == '\\') - { - value = value.substring(1); - } - if (oid.equals(dc)) - { - return new DERIA5String(value); - } - else if (oid.equals(c) || oid.equals(serialNumber) || oid.equals(dnQualifier) - || oid.equals(telephoneNumber)) - { - return new DERPrintableString(value); - } - } - - return new DERUTF8String(value); - } - - public String oidToDisplayName(ASN1ObjectIdentifier oid) - { - return (String)DefaultSymbols.get(oid); - } - - public String[] oidToAttrNames(ASN1ObjectIdentifier oid) - { - return IETFUtils.findAttrNamesForOID(oid, defaultLookUp); - } - - public ASN1ObjectIdentifier attrNameToOID(String attrName) - { - return IETFUtils.decodeAttrName(attrName, defaultLookUp); - } - - public boolean areEqual(X500Name name1, X500Name name2) - { - RDN[] rdns1 = name1.getRDNs(); - RDN[] rdns2 = name2.getRDNs(); - - if (rdns1.length != rdns2.length) - { - return false; - } - - boolean reverse = false; - - if (rdns1[0].getFirst() != null && rdns2[0].getFirst() != null) - { - reverse = !rdns1[0].getFirst().getType().equals(rdns2[0].getFirst().getType()); // guess forward - } - - for (int i = 0; i != rdns1.length; i++) - { - if (!foundMatch(reverse, rdns1[i], rdns2)) - { - return false; - } - } - - return true; - } - - private boolean foundMatch(boolean reverse, RDN rdn, RDN[] possRDNs) - { - if (reverse) - { - for (int i = possRDNs.length - 1; i >= 0; i--) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - else - { - for (int i = 0; i != possRDNs.length; i++) - { - if (possRDNs[i] != null && rdnAreEqual(rdn, possRDNs[i])) - { - possRDNs[i] = null; - return true; - } - } - } - - return false; - } - - protected boolean rdnAreEqual(RDN rdn1, RDN rdn2) - { - return IETFUtils.rDNAreEqual(rdn1, rdn2); - } - - // parse backwards - public RDN[] fromString(String dirName) - { - RDN[] tmp = IETFUtils.rDNsFromString(dirName, this); - RDN[] res = new RDN[tmp.length]; - - for (int i = 0; i != tmp.length; i++) - { - res[res.length - i - 1] = tmp[i]; - } - - return res; - } - - public int calculateHashCode(X500Name name) - { - int hashCodeValue = 0; - RDN[] rdns = name.getRDNs(); - - // this needs to be order independent, like equals - for (int i = 0; i != rdns.length; i++) - { - if (rdns[i].isMultiValued()) - { - AttributeTypeAndValue[] atv = rdns[i].getTypesAndValues(); - - for (int j = 0; j != atv.length; j++) - { - hashCodeValue ^= atv[j].getType().hashCode(); - hashCodeValue ^= calcHashCode(atv[j].getValue()); - } - } - else - { - hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); - hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); - } - } - - return hashCodeValue; - } - - private int calcHashCode(ASN1Encodable enc) - { - String value = IETFUtils.valueToString(enc); - - value = IETFUtils.canonicalize(value); - - return value.hashCode(); - } - - // convert in reverse - public String toString(X500Name name) - { - StringBuffer buf = new StringBuffer(); - boolean first = true; - - RDN[] rdns = name.getRDNs(); - - for (int i = rdns.length - 1; i >= 0; i--) - { - if (first) - { - first = false; - } - else - { - buf.append(','); - } - - IETFUtils.appendRDN(buf, rdns[i], defaultSymbols); - } - - return buf.toString(); - } - - private static Hashtable copyHashTable(Hashtable paramsMap) - { - Hashtable newTable = new Hashtable(); - - Enumeration keys = paramsMap.keys(); - while (keys.hasMoreElements()) - { - Object key = keys.nextElement(); - newTable.put(key, paramsMap.get(key)); - } - - return newTable; - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java deleted file mode 100644 index 30808802..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEParticipant.java +++ /dev/null @@ -1,573 +0,0 @@ -package org.bouncycastle.crypto.agreement.jpake; - -import java.math.BigInteger; -import java.security.SecureRandom; - -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.util.Arrays; - -/** - * A participant in a Password Authenticated Key Exchange by Juggling (J-PAKE) exchange. - * <p/> - * <p/> - * The J-PAKE exchange is defined by Feng Hao and Peter Ryan in the paper - * <a href="http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf"> - * "Password Authenticated Key Exchange by Juggling, 2008."</a> - * <p/> - * <p/> - * The J-PAKE protocol is symmetric. - * There is no notion of a <i>client</i> or <i>server</i>, but rather just two <i>participants</i>. - * An instance of {@link JPAKEParticipant} represents one participant, and - * is the primary interface for executing the exchange. - * <p/> - * <p/> - * To execute an exchange, construct a {@link JPAKEParticipant} on each end, - * and call the following 7 methods - * (once and only once, in the given order, for each participant, sending messages between them as described): - * <ol> - * <li>{@link #createRound1PayloadToSend()} - and send the payload to the other participant</li> - * <li>{@link #validateRound1PayloadReceived(JPAKERound1Payload)} - use the payload received from the other participant</li> - * <li>{@link #createRound2PayloadToSend()} - and send the payload to the other participant</li> - * <li>{@link #validateRound2PayloadReceived(JPAKERound2Payload)} - use the payload received from the other participant</li> - * <li>{@link #calculateKeyingMaterial()}</li> - * <li>{@link #createRound3PayloadToSend(BigInteger)} - and send the payload to the other participant</li> - * <li>{@link #validateRound3PayloadReceived(JPAKERound3Payload, BigInteger)} - use the payload received from the other participant</li> - * </ol> - * <p/> - * <p/> - * Each side should derive a session key from the keying material returned by {@link #calculateKeyingMaterial()}. - * The caller is responsible for deriving the session key using a secure key derivation function (KDF). - * <p/> - * <p/> - * Round 3 is an optional key confirmation process. - * If you do not execute round 3, then there is no assurance that both participants are using the same key. - * (i.e. if the participants used different passwords, then their session keys will differ.) - * <p/> - * <p/> - * If the round 3 validation succeeds, then the keys are guaranteed to be the same on both sides. - * <p/> - * <p/> - * The symmetric design can easily support the asymmetric cases when one party initiates the communication. - * e.g. Sometimes the round1 payload and round2 payload may be sent in one pass. - * Also, in some cases, the key confirmation payload can be sent together with the round2 payload. - * These are the trivial techniques to optimize the communication. - * <p/> - * <p/> - * The key confirmation process is implemented as specified in - * <a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">NIST SP 800-56A Revision 1</a>, - * Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes. - * <p/> - * <p/> - * This class is stateful and NOT threadsafe. - * Each instance should only be used for ONE complete J-PAKE exchange - * (i.e. a new {@link JPAKEParticipant} should be constructed for each new J-PAKE exchange). - * <p/> - * <p/> - * See {@link JPAKEExample} for example usage. - */ -public class JPAKEParticipant -{ - /* - * Possible internal states. Used for state checking. - */ - - public static final int STATE_INITIALIZED = 0; - public static final int STATE_ROUND_1_CREATED = 10; - public static final int STATE_ROUND_1_VALIDATED = 20; - public static final int STATE_ROUND_2_CREATED = 30; - public static final int STATE_ROUND_2_VALIDATED = 40; - public static final int STATE_KEY_CALCULATED = 50; - public static final int STATE_ROUND_3_CREATED = 60; - public static final int STATE_ROUND_3_VALIDATED = 70; - - /** - * Unique identifier of this participant. - * The two participants in the exchange must NOT share the same id. - */ - private String participantId; - - /** - * Shared secret. This only contains the secret between construction - * and the call to {@link #calculateKeyingMaterial()}. - * <p/> - * i.e. When {@link #calculateKeyingMaterial()} is called, this buffer overwritten with 0's, - * and the field is set to null. - */ - private char[] password; - - /** - * Digest to use during calculations. - */ - private Digest digest; - - /** - * Source of secure random data. - */ - private SecureRandom random; - - private BigInteger p; - private BigInteger q; - private BigInteger g; - - /** - * The participantId of the other participant in this exchange. - */ - private String partnerParticipantId; - - /** - * Alice's x1 or Bob's x3. - */ - private BigInteger x1; - /** - * Alice's x2 or Bob's x4. - */ - private BigInteger x2; - /** - * Alice's g^x1 or Bob's g^x3. - */ - private BigInteger gx1; - /** - * Alice's g^x2 or Bob's g^x4. - */ - private BigInteger gx2; - /** - * Alice's g^x3 or Bob's g^x1. - */ - private BigInteger gx3; - /** - * Alice's g^x4 or Bob's g^x2. - */ - private BigInteger gx4; - /** - * Alice's B or Bob's A. - */ - private BigInteger b; - - /** - * The current state. - * See the <tt>STATE_*</tt> constants for possible values. - */ - private int state; - - /** - * Convenience constructor for a new {@link JPAKEParticipant} that uses - * the {@link JPAKEPrimeOrderGroups#NIST_3072} prime order group, - * a SHA-256 digest, and a default {@link SecureRandom} implementation. - * <p/> - * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. - * - * @param participantId unique identifier of this participant. - * The two participants in the exchange must NOT share the same id. - * @param password shared secret. - * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). - * Caller should clear the input password as soon as possible. - * @throws NullPointerException if any argument is null - * @throws IllegalArgumentException if password is empty - */ - public JPAKEParticipant( - String participantId, - char[] password) - { - this( - participantId, - password, - JPAKEPrimeOrderGroups.NIST_3072); - } - - - /** - * Convenience constructor for a new {@link JPAKEParticipant} that uses - * a SHA-256 digest and a default {@link SecureRandom} implementation. - * <p/> - * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. - * - * @param participantId unique identifier of this participant. - * The two participants in the exchange must NOT share the same id. - * @param password shared secret. - * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). - * Caller should clear the input password as soon as possible. - * @param group prime order group. - * See {@link JPAKEPrimeOrderGroups} for standard groups - * @throws NullPointerException if any argument is null - * @throws IllegalArgumentException if password is empty - */ - public JPAKEParticipant( - String participantId, - char[] password, - JPAKEPrimeOrderGroup group) - { - this( - participantId, - password, - group, - new SHA256Digest(), - new SecureRandom()); - } - - - /** - * Construct a new {@link JPAKEParticipant}. - * <p/> - * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}. - * - * @param participantId unique identifier of this participant. - * The two participants in the exchange must NOT share the same id. - * @param password shared secret. - * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called). - * Caller should clear the input password as soon as possible. - * @param group prime order group. - * See {@link JPAKEPrimeOrderGroups} for standard groups - * @param digest digest to use during zero knowledge proofs and key confirmation (SHA-256 or stronger preferred) - * @param random source of secure random data for x1 and x2, and for the zero knowledge proofs - * @throws NullPointerException if any argument is null - * @throws IllegalArgumentException if password is empty - */ - public JPAKEParticipant( - String participantId, - char[] password, - JPAKEPrimeOrderGroup group, - Digest digest, - SecureRandom random) - { - JPAKEUtil.validateNotNull(participantId, "participantId"); - JPAKEUtil.validateNotNull(password, "password"); - JPAKEUtil.validateNotNull(group, "p"); - JPAKEUtil.validateNotNull(digest, "digest"); - JPAKEUtil.validateNotNull(random, "random"); - if (password.length == 0) - { - throw new IllegalArgumentException("Password must not be empty."); - } - - this.participantId = participantId; - - /* - * Create a defensive copy so as to fully encapsulate the password. - * - * This array will contain the password for the lifetime of this - * participant BEFORE {@link #calculateKeyingMaterial()} is called. - * - * i.e. When {@link #calculateKeyingMaterial()} is called, the array will be cleared - * in order to remove the password from memory. - * - * The caller is responsible for clearing the original password array - * given as input to this constructor. - */ - this.password = Arrays.copyOf(password, password.length); - - this.p = group.getP(); - this.q = group.getQ(); - this.g = group.getG(); - - this.digest = digest; - this.random = random; - - this.state = STATE_INITIALIZED; - } - - /** - * Gets the current state of this participant. - * See the <tt>STATE_*</tt> constants for possible values. - */ - public int getState() - { - return this.state; - } - - /** - * Creates and returns the payload to send to the other participant during round 1. - * <p/> - * <p/> - * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_CREATED}. - */ - public JPAKERound1Payload createRound1PayloadToSend() - { - if (this.state >= STATE_ROUND_1_CREATED) - { - throw new IllegalStateException("Round1 payload already created for " + participantId); - } - - this.x1 = JPAKEUtil.generateX1(q, random); - this.x2 = JPAKEUtil.generateX2(q, random); - - this.gx1 = JPAKEUtil.calculateGx(p, g, x1); - this.gx2 = JPAKEUtil.calculateGx(p, g, x2); - BigInteger[] knowledgeProofForX1 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random); - BigInteger[] knowledgeProofForX2 = JPAKEUtil.calculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random); - - this.state = STATE_ROUND_1_CREATED; - - return new JPAKERound1Payload(participantId, gx1, gx2, knowledgeProofForX1, knowledgeProofForX2); - } - - /** - * Validates the payload received from the other participant during round 1. - * <p/> - * <p/> - * Must be called prior to {@link #createRound2PayloadToSend()}. - * <p/> - * <p/> - * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}. - * - * @throws CryptoException if validation fails. - * @throws IllegalStateException if called multiple times. - */ - public void validateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived) - throws CryptoException - { - if (this.state >= STATE_ROUND_1_VALIDATED) - { - throw new IllegalStateException("Validation already attempted for round1 payload for" + participantId); - } - this.partnerParticipantId = round1PayloadReceived.getParticipantId(); - this.gx3 = round1PayloadReceived.getGx1(); - this.gx4 = round1PayloadReceived.getGx2(); - - BigInteger[] knowledgeProofForX3 = round1PayloadReceived.getKnowledgeProofForX1(); - BigInteger[] knowledgeProofForX4 = round1PayloadReceived.getKnowledgeProofForX2(); - - JPAKEUtil.validateParticipantIdsDiffer(participantId, round1PayloadReceived.getParticipantId()); - JPAKEUtil.validateGx4(gx4); - JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.getParticipantId(), digest); - JPAKEUtil.validateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.getParticipantId(), digest); - - this.state = STATE_ROUND_1_VALIDATED; - } - - /** - * Creates and returns the payload to send to the other participant during round 2. - * <p/> - * <p/> - * {@link #validateRound1PayloadReceived(JPAKERound1Payload)} must be called prior to this method. - * <p/> - * <p/> - * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_CREATED}. - * - * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times - */ - public JPAKERound2Payload createRound2PayloadToSend() - { - if (this.state >= STATE_ROUND_2_CREATED) - { - throw new IllegalStateException("Round2 payload already created for " + this.participantId); - } - if (this.state < STATE_ROUND_1_VALIDATED) - { - throw new IllegalStateException("Round1 payload must be validated prior to creating Round2 payload for " + this.participantId); - } - BigInteger gA = JPAKEUtil.calculateGA(p, gx1, gx3, gx4); - BigInteger s = JPAKEUtil.calculateS(password); - BigInteger x2s = JPAKEUtil.calculateX2s(q, x2, s); - BigInteger A = JPAKEUtil.calculateA(p, q, gA, x2s); - BigInteger[] knowledgeProofForX2s = JPAKEUtil.calculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random); - - this.state = STATE_ROUND_2_CREATED; - - return new JPAKERound2Payload(participantId, A, knowledgeProofForX2s); - } - - /** - * Validates the payload received from the other participant during round 2. - * <p/> - * <p/> - * Note that this DOES NOT detect a non-common password. - * The only indication of a non-common password is through derivation - * of different keys (which can be detected explicitly by executing round 3 and round 4) - * <p/> - * <p/> - * Must be called prior to {@link #calculateKeyingMaterial()}. - * <p/> - * <p/> - * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_VALIDATED}. - * - * @throws CryptoException if validation fails. - * @throws IllegalStateException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times - */ - public void validateRound2PayloadReceived(JPAKERound2Payload round2PayloadReceived) - throws CryptoException - { - if (this.state >= STATE_ROUND_2_VALIDATED) - { - throw new IllegalStateException("Validation already attempted for round2 payload for" + participantId); - } - if (this.state < STATE_ROUND_1_VALIDATED) - { - throw new IllegalStateException("Round1 payload must be validated prior to validating Round2 payload for " + this.participantId); - } - BigInteger gB = JPAKEUtil.calculateGA(p, gx3, gx1, gx2); - this.b = round2PayloadReceived.getA(); - BigInteger[] knowledgeProofForX4s = round2PayloadReceived.getKnowledgeProofForX2s(); - - JPAKEUtil.validateParticipantIdsDiffer(participantId, round2PayloadReceived.getParticipantId()); - JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round2PayloadReceived.getParticipantId()); - JPAKEUtil.validateGa(gB); - JPAKEUtil.validateZeroKnowledgeProof(p, q, gB, b, knowledgeProofForX4s, round2PayloadReceived.getParticipantId(), digest); - - this.state = STATE_ROUND_2_VALIDATED; - } - - /** - * Calculates and returns the key material. - * A session key must be derived from this key material using a secure key derivation function (KDF). - * The KDF used to derive the key is handled externally (i.e. not by {@link JPAKEParticipant}). - * <p/> - * <p/> - * The keying material will be identical for each participant if and only if - * each participant's password is the same. i.e. If the participants do not - * share the same password, then each participant will derive a different key. - * Therefore, if you immediately start using a key derived from - * the keying material, then you must handle detection of incorrect keys. - * If you want to handle this detection explicitly, you can optionally perform - * rounds 3 and 4. See {@link JPAKEParticipant} for details on how to execute - * rounds 3 and 4. - * <p/> - * <p/> - * The keying material will be in the range <tt>[0, p-1]</tt>. - * <p/> - * <p/> - * {@link #validateRound2PayloadReceived(JPAKERound2Payload)} must be called prior to this method. - * <p/> - * <p/> - * As a side effect, the internal {@link #password} array is cleared, since it is no longer needed. - * <p/> - * <p/> - * After execution, the {@link #getState() state} will be {@link #STATE_KEY_CALCULATED}. - * - * @throws IllegalStateException if called prior to {@link #validateRound2PayloadReceived(JPAKERound2Payload)}, - * or if called multiple times. - */ - public BigInteger calculateKeyingMaterial() - { - if (this.state >= STATE_KEY_CALCULATED) - { - throw new IllegalStateException("Key already calculated for " + participantId); - } - if (this.state < STATE_ROUND_2_VALIDATED) - { - throw new IllegalStateException("Round2 payload must be validated prior to creating key for " + participantId); - } - BigInteger s = JPAKEUtil.calculateS(password); - - /* - * Clear the password array from memory, since we don't need it anymore. - * - * Also set the field to null as a flag to indicate that the key has already been calculated. - */ - Arrays.fill(password, (char)0); - this.password = null; - - BigInteger keyingMaterial = JPAKEUtil.calculateKeyingMaterial(p, q, gx4, x2, s, b); - - /* - * Clear the ephemeral private key fields as well. - * Note that we're relying on the garbage collector to do its job to clean these up. - * The old objects will hang around in memory until the garbage collector destroys them. - * - * If the ephemeral private keys x1 and x2 are leaked, - * the attacker might be able to brute-force the password. - */ - this.x1 = null; - this.x2 = null; - this.b = null; - - /* - * Do not clear gx* yet, since those are needed by round 3. - */ - - this.state = STATE_KEY_CALCULATED; - - return keyingMaterial; - } - - - /** - * Creates and returns the payload to send to the other participant during round 3. - * <p/> - * <p/> - * See {@link JPAKEParticipant} for more details on round 3. - * <p/> - * <p/> - * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_CREATED}. - * - * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}. - * @throws IllegalStateException if called prior to {@link #calculateKeyingMaterial()}, or multiple times - */ - public JPAKERound3Payload createRound3PayloadToSend(BigInteger keyingMaterial) - { - if (this.state >= STATE_ROUND_3_CREATED) - { - throw new IllegalStateException("Round3 payload already created for " + this.participantId); - } - if (this.state < STATE_KEY_CALCULATED) - { - throw new IllegalStateException("Keying material must be calculated prior to creating Round3 payload for " + this.participantId); - } - - BigInteger macTag = JPAKEUtil.calculateMacTag( - this.participantId, - this.partnerParticipantId, - this.gx1, - this.gx2, - this.gx3, - this.gx4, - keyingMaterial, - this.digest); - - this.state = STATE_ROUND_3_CREATED; - - return new JPAKERound3Payload(participantId, macTag); - } - - /** - * Validates the payload received from the other participant during round 3. - * <p/> - * <p/> - * See {@link JPAKEParticipant} for more details on round 3. - * <p/> - * <p/> - * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_VALIDATED}. - * - * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}. - * @throws CryptoException if validation fails. - * @throws IllegalStateException if called prior to {@link #calculateKeyingMaterial()}, or multiple times - */ - public void validateRound3PayloadReceived(JPAKERound3Payload round3PayloadReceived, BigInteger keyingMaterial) - throws CryptoException - { - if (this.state >= STATE_ROUND_3_VALIDATED) - { - throw new IllegalStateException("Validation already attempted for round3 payload for" + participantId); - } - if (this.state < STATE_KEY_CALCULATED) - { - throw new IllegalStateException("Keying material must be calculated validated prior to validating Round3 payload for " + this.participantId); - } - JPAKEUtil.validateParticipantIdsDiffer(participantId, round3PayloadReceived.getParticipantId()); - JPAKEUtil.validateParticipantIdsEqual(this.partnerParticipantId, round3PayloadReceived.getParticipantId()); - - JPAKEUtil.validateMacTag( - this.participantId, - this.partnerParticipantId, - this.gx1, - this.gx2, - this.gx3, - this.gx4, - keyingMaterial, - this.digest, - round3PayloadReceived.getMacTag()); - - - /* - * Clear the rest of the fields. - */ - this.gx1 = null; - this.gx2 = null; - this.gx3 = null; - this.gx4 = null; - - this.state = STATE_ROUND_3_VALIDATED; - } - -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEPrimeOrderGroup.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEPrimeOrderGroup.java deleted file mode 100644 index 5a2f4022..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/agreement/jpake/JPAKEPrimeOrderGroup.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.bouncycastle.crypto.agreement.jpake; - -import java.math.BigInteger; - -/** - * A pre-computed prime order group for use during a J-PAKE exchange. - * <p/> - * <p/> - * Typically a Schnorr group is used. In general, J-PAKE can use any prime order group - * that is suitable for public key cryptography, including elliptic curve cryptography. - * <p/> - * <p/> - * See {@link JPAKEPrimeOrderGroups} for convenient standard groups. - * <p/> - * <p/> - * NIST <a href="http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/DSA2_All.pdf">publishes</a> - * many groups that can be used for the desired level of security. - */ -public class JPAKEPrimeOrderGroup -{ - private BigInteger p; - private BigInteger q; - private BigInteger g; - - /** - * Constructs a new {@link JPAKEPrimeOrderGroup}. - * <p/> - * <p/> - * In general, you should use one of the pre-approved groups from - * {@link JPAKEPrimeOrderGroups}, rather than manually constructing one. - * <p/> - * <p/> - * The following basic checks are performed: - * <ul> - * <li>p-1 must be evenly divisible by q</li> - * <li>g must be in [2, p-1]</li> - * <li>g^q mod p must equal 1</li> - * <li>p must be prime (within reasonably certainty)</li> - * <li>q must be prime (within reasonably certainty)</li> - * </ul> - * <p/> - * <p/> - * The prime checks are performed using {@link BigInteger#isProbablePrime(int)}, - * and are therefore subject to the same probability guarantees. - * <p/> - * <p/> - * These checks prevent trivial mistakes. - * However, due to the small uncertainties if p and q are not prime, - * advanced attacks are not prevented. - * Use it at your own risk. - * - * @throws NullPointerException if any argument is null - * @throws IllegalArgumentException if any of the above validations fail - */ - public JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g) - { - /* - * Don't skip the checks on user-specified groups. - */ - this(p, q, g, false); - } - - /** - * Internal package-private constructor used by the pre-approved - * groups in {@link JPAKEPrimeOrderGroups}. - * These pre-approved groups can avoid the expensive checks. - */ - JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, boolean skipChecks) - { - JPAKEUtil.validateNotNull(p, "p"); - JPAKEUtil.validateNotNull(q, "q"); - JPAKEUtil.validateNotNull(g, "g"); - - if (!skipChecks) - { - if (!p.subtract(JPAKEUtil.ONE).mod(q).equals(JPAKEUtil.ZERO)) - { - throw new IllegalArgumentException("p-1 must be evenly divisible by q"); - } - if (g.compareTo(BigInteger.valueOf(2)) == -1 || g.compareTo(p.subtract(JPAKEUtil.ONE)) == 1) - { - throw new IllegalArgumentException("g must be in [2, p-1]"); - } - if (!g.modPow(q, p).equals(JPAKEUtil.ONE)) - { - throw new IllegalArgumentException("g^q mod p must equal 1"); - } - /* - * Note that these checks do not guarantee that p and q are prime. - * We just have reasonable certainty that they are prime. - */ - if (!p.isProbablePrime(20)) - { - throw new IllegalArgumentException("p must be prime"); - } - if (!q.isProbablePrime(20)) - { - throw new IllegalArgumentException("q must be prime"); - } - } - - this.p = p; - this.q = q; - this.g = g; - } - - public BigInteger getP() - { - return p; - } - - public BigInteger getQ() - { - return q; - } - - public BigInteger getG() - { - return g; - } - -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/digests/SkeinEngine.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/digests/SkeinEngine.java deleted file mode 100644 index 5bfee7e6..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/digests/SkeinEngine.java +++ /dev/null @@ -1,817 +0,0 @@ -package org.bouncycastle.crypto.digests; - -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.engines.ThreefishEngine; -import org.bouncycastle.crypto.macs.SkeinMac; -import org.bouncycastle.crypto.params.SkeinParameters; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Memoable; - -/** - * Implementation of the Skein family of parameterised hash functions in 256, 512 and 1024 bit block - * sizes, based on the {@link ThreefishEngine Threefish} tweakable block cipher. - * <p/> - * This is the 1.3 version of Skein defined in the Skein hash function submission to the NIST SHA-3 - * competition in October 2010. - * <p/> - * Skein was designed by Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting - Mihir - * Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker. - * <p/> - * This implementation is the basis for {@link SkeinDigest} and {@link SkeinMac}, implementing the - * parameter based configuration system that allows Skein to be adapted to multiple applications. <br> - * Initialising the engine with {@link SkeinParameters} allows standard and arbitrary parameters to - * be applied during the Skein hash function. - * <p/> - * Implemented: - * <ul> - * <li>256, 512 and 1024 bit internal states.</li> - * <li>Full 96 bit input length.</li> - * <li>Parameters defined in the Skein specification, and arbitrary other pre and post message - * parameters.</li> - * <li>Arbitrary output size in 1 byte intervals.</li> - * </ul> - * <p/> - * Not implemented: - * <ul> - * <li>Sub-byte length input (bit padding).</li> - * <li>Tree hashing.</li> - * </ul> - * - * @see SkeinParameters - */ -public class SkeinEngine - implements Memoable -{ - /** - * 256 bit block size - Skein 256 - */ - public static final int SKEIN_256 = ThreefishEngine.BLOCKSIZE_256; - /** - * 512 bit block size - Skein 512 - */ - public static final int SKEIN_512 = ThreefishEngine.BLOCKSIZE_512; - /** - * 1024 bit block size - Skein 1024 - */ - public static final int SKEIN_1024 = ThreefishEngine.BLOCKSIZE_1024; - - // Minimal at present, but more complex when tree hashing is implemented - private static class Configuration - { - private byte[] bytes = new byte[32]; - - public Configuration(long outputSizeBits) - { - // 0..3 = ASCII SHA3 - bytes[0] = (byte)'S'; - bytes[1] = (byte)'H'; - bytes[2] = (byte)'A'; - bytes[3] = (byte)'3'; - - // 4..5 = version number in LSB order - bytes[4] = 1; - bytes[5] = 0; - - // 8..15 = output length - ThreefishEngine.wordToBytes(outputSizeBits, bytes, 8); - } - - public byte[] getBytes() - { - return bytes; - } - - } - - public static class Parameter - { - private int type; - private byte[] value; - - public Parameter(int type, byte[] value) - { - this.type = type; - this.value = value; - } - - public int getType() - { - return type; - } - - public byte[] getValue() - { - return value; - } - - } - - /** - * The parameter type for the Skein key. - */ - private static final int PARAM_TYPE_KEY = 0; - - /** - * The parameter type for the Skein configuration block. - */ - private static final int PARAM_TYPE_CONFIG = 4; - - /** - * The parameter type for the message. - */ - private static final int PARAM_TYPE_MESSAGE = 48; - - /** - * The parameter type for the output transformation. - */ - private static final int PARAM_TYPE_OUTPUT = 63; - - /** - * Precalculated UBI(CFG) states for common state/output combinations without key or other - * pre-message params. - */ - private static final Hashtable INITIAL_STATES = new Hashtable(); - - static - { - // From Appendix C of the Skein 1.3 NIST submission - initialState(SKEIN_256, 128, new long[]{ - 0xe1111906964d7260L, - 0x883daaa77c8d811cL, - 0x10080df491960f7aL, - 0xccf7dde5b45bc1c2L}); - - initialState(SKEIN_256, 160, new long[]{ - 0x1420231472825e98L, - 0x2ac4e9a25a77e590L, - 0xd47a58568838d63eL, - 0x2dd2e4968586ab7dL}); - - initialState(SKEIN_256, 224, new long[]{ - 0xc6098a8c9ae5ea0bL, - 0x876d568608c5191cL, - 0x99cb88d7d7f53884L, - 0x384bddb1aeddb5deL}); - - initialState(SKEIN_256, 256, new long[]{ - 0xfc9da860d048b449L, - 0x2fca66479fa7d833L, - 0xb33bc3896656840fL, - 0x6a54e920fde8da69L}); - - initialState(SKEIN_512, 128, new long[]{ - 0xa8bc7bf36fbf9f52L, - 0x1e9872cebd1af0aaL, - 0x309b1790b32190d3L, - 0xbcfbb8543f94805cL, - 0x0da61bcd6e31b11bL, - 0x1a18ebead46a32e3L, - 0xa2cc5b18ce84aa82L, - 0x6982ab289d46982dL}); - - initialState(SKEIN_512, 160, new long[]{ - 0x28b81a2ae013bd91L, - 0xc2f11668b5bdf78fL, - 0x1760d8f3f6a56f12L, - 0x4fb747588239904fL, - 0x21ede07f7eaf5056L, - 0xd908922e63ed70b8L, - 0xb8ec76ffeccb52faL, - 0x01a47bb8a3f27a6eL}); - - initialState(SKEIN_512, 224, new long[]{ - 0xccd0616248677224L, - 0xcba65cf3a92339efL, - 0x8ccd69d652ff4b64L, - 0x398aed7b3ab890b4L, - 0x0f59d1b1457d2bd0L, - 0x6776fe6575d4eb3dL, - 0x99fbc70e997413e9L, - 0x9e2cfccfe1c41ef7L}); - - initialState(SKEIN_512, 384, new long[]{ - 0xa3f6c6bf3a75ef5fL, - 0xb0fef9ccfd84faa4L, - 0x9d77dd663d770cfeL, - 0xd798cbf3b468fddaL, - 0x1bc4a6668a0e4465L, - 0x7ed7d434e5807407L, - 0x548fc1acd4ec44d6L, - 0x266e17546aa18ff8L}); - - initialState(SKEIN_512, 512, new long[]{ - 0x4903adff749c51ceL, - 0x0d95de399746df03L, - 0x8fd1934127c79bceL, - 0x9a255629ff352cb1L, - 0x5db62599df6ca7b0L, - 0xeabe394ca9d5c3f4L, - 0x991112c71a75b523L, - 0xae18a40b660fcc33L}); - } - - private static void initialState(int blockSize, int outputSize, long[] state) - { - INITIAL_STATES.put(variantIdentifier(blockSize / 8, outputSize / 8), state); - } - - private static Integer variantIdentifier(int blockSizeBytes, int outputSizeBytes) - { - return new Integer((outputSizeBytes << 16) | blockSizeBytes); - } - - private static class UbiTweak - { - /** - * Point at which position might overflow long, so switch to add with carry logic - */ - private static final long LOW_RANGE = Long.MAX_VALUE - Integer.MAX_VALUE; - - /** - * Bit 127 = final - */ - private static final long T1_FINAL = 1L << 63; - - /** - * Bit 126 = first - */ - private static final long T1_FIRST = 1L << 62; - - /** - * UBI uses a 128 bit tweak - */ - private long tweak[] = new long[2]; - - /** - * Whether 64 bit position exceeded - */ - private boolean extendedPosition; - - public UbiTweak() - { - reset(); - } - - public void reset(UbiTweak tweak) - { - this.tweak = Arrays.clone(tweak.tweak, this.tweak); - this.extendedPosition = tweak.extendedPosition; - } - - public void reset() - { - tweak[0] = 0; - tweak[1] = 0; - extendedPosition = false; - setFirst(true); - } - - public void setType(int type) - { - // Bits 120..125 = type - tweak[1] = (tweak[1] & 0xFFFFFFC000000000L) | ((type & 0x3FL) << 56); - } - - public int getType() - { - return (int)((tweak[1] >>> 56) & 0x3FL); - } - - public void setFirst(boolean first) - { - if (first) - { - tweak[1] |= T1_FIRST; - } - else - { - tweak[1] &= ~T1_FIRST; - } - } - - public boolean isFirst() - { - return ((tweak[1] & T1_FIRST) != 0); - } - - public void setFinal(boolean last) - { - if (last) - { - tweak[1] |= T1_FINAL; - } - else - { - tweak[1] &= ~T1_FINAL; - } - } - - public boolean isFinal() - { - return ((tweak[1] & T1_FINAL) != 0); - } - - /** - * Advances the position in the tweak by the specified value. - */ - public void advancePosition(int advance) - { - // Bits 0..95 = position - if (extendedPosition) - { - long[] parts = new long[3]; - parts[0] = tweak[0] & 0xFFFFFFFFL; - parts[1] = (tweak[0] >>> 32) & 0xFFFFFFFFL; - parts[2] = tweak[1] & 0xFFFFFFFFL; - - long carry = advance; - for (int i = 0; i < parts.length; i++) - { - carry += parts[i]; - parts[i] = carry; - carry >>>= 32; - } - tweak[0] = ((parts[1] & 0xFFFFFFFFL) << 32) | (parts[0] & 0xFFFFFFFFL); - tweak[1] = (tweak[1] & 0xFFFFFFFF00000000L) | (parts[2] & 0xFFFFFFFFL); - } - else - { - long position = tweak[0]; - position += advance; - tweak[0] = position; - if (position > LOW_RANGE) - { - extendedPosition = true; - } - } - } - - public long[] getWords() - { - return tweak; - } - - public String toString() - { - return getType() + " first: " + isFirst() + ", final: " + isFinal(); - } - - } - - /** - * The Unique Block Iteration chaining mode. - */ - // TODO: This might be better as methods... - private class UBI - { - private final UbiTweak tweak = new UbiTweak(); - - /** - * Buffer for the current block of message data - */ - private byte[] currentBlock; - - /** - * Offset into the current message block - */ - private int currentOffset; - - /** - * Buffer for message words for feedback into encrypted block - */ - private long[] message; - - public UBI(int blockSize) - { - currentBlock = new byte[blockSize]; - message = new long[currentBlock.length / 8]; - } - - public void reset(UBI ubi) - { - currentBlock = Arrays.clone(ubi.currentBlock, currentBlock); - currentOffset = ubi.currentOffset; - message = Arrays.clone(ubi.message, this.message); - tweak.reset(ubi.tweak); - } - - public void reset(int type) - { - tweak.reset(); - tweak.setType(type); - currentOffset = 0; - } - - public void update(byte[] value, int offset, int len, long[] output) - { - /* - * Buffer complete blocks for the underlying Threefish cipher, only flushing when there - * are subsequent bytes (last block must be processed in doFinal() with final=true set). - */ - int copied = 0; - while (len > copied) - { - if (currentOffset == currentBlock.length) - { - processBlock(output); - tweak.setFirst(false); - currentOffset = 0; - } - - int toCopy = Math.min((len - copied), currentBlock.length - currentOffset); - System.arraycopy(value, offset + copied, currentBlock, currentOffset, toCopy); - copied += toCopy; - currentOffset += toCopy; - tweak.advancePosition(toCopy); - } - } - - private void processBlock(long[] output) - { - threefish.init(true, chain, tweak.getWords()); - for (int i = 0; i < message.length; i++) - { - message[i] = ThreefishEngine.bytesToWord(currentBlock, i * 8); - } - - threefish.processBlock(message, output); - - for (int i = 0; i < output.length; i++) - { - output[i] ^= message[i]; - } - } - - public void doFinal(long[] output) - { - // Pad remainder of current block with zeroes - for (int i = currentOffset; i < currentBlock.length; i++) - { - currentBlock[i] = 0; - } - - tweak.setFinal(true); - processBlock(output); - } - - } - - /** - * Underlying Threefish tweakable block cipher - */ - private ThreefishEngine threefish; - - /** - * Size of the digest output, in bytes - */ - private int outputSizeBytes; - - /** - * The current chaining/state value - */ - long[] chain; - - /** - * The initial state value - */ - private long[] initialState; - - /** - * The (optional) key parameter - */ - private byte[] key; - - /** - * Parameters to apply prior to the message - */ - private Parameter[] preMessageParameters; - - /** - * Parameters to apply after the message, but prior to output - */ - private Parameter[] postMessageParameters; - - /** - * The current UBI operation - */ - private UBI ubi; - - /** - * Buffer for single byte update method - */ - private final byte[] singleByte = new byte[1]; - - /** - * Constructs a Skein engine. - * - * @param blockSizeBits the internal state size in bits - one of {@link #SKEIN_256}, {@link #SKEIN_512} or - * {@link #SKEIN_1024}. - * @param outputSizeBits the output/digest size to produce in bits, which must be an integral number of - * bytes. - */ - public SkeinEngine(int blockSizeBits, int outputSizeBits) - { - if (outputSizeBits % 8 != 0) - { - throw new IllegalArgumentException("Output size must be a multiple of 8 bits. :" + outputSizeBits); - } - // TODO: Prevent digest sizes > block size? - this.outputSizeBytes = outputSizeBits / 8; - - this.threefish = new ThreefishEngine(blockSizeBits); - this.ubi = new UBI(threefish.getBlockSize()); - } - - /** - * Creates a SkeinEngine as an exact copy of an existing instance. - */ - public SkeinEngine(SkeinEngine engine) - { - this(engine.getBlockSize() * 8, engine.getOutputSize() * 8); - copyIn(engine); - } - - private void copyIn(SkeinEngine engine) - { - this.ubi.reset(engine.ubi); - this.chain = Arrays.clone(engine.chain, this.chain); - this.initialState = Arrays.clone(engine.initialState, this.initialState); - this.key = Arrays.clone(engine.key, this.key); - this.preMessageParameters = clone(engine.preMessageParameters, this.preMessageParameters); - this.postMessageParameters = clone(engine.postMessageParameters, this.postMessageParameters); - } - - private static Parameter[] clone(Parameter[] data, Parameter[] existing) - { - if (data == null) - { - return null; - } - if ((existing == null) || (existing.length != data.length)) - { - existing = new Parameter[data.length]; - } - System.arraycopy(data, 0, existing, 0, existing.length); - return existing; - } - - public Memoable copy() - { - return new SkeinEngine(this); - } - - public void reset(Memoable other) - { - SkeinEngine s = (SkeinEngine)other; - if ((getBlockSize() != s.getBlockSize()) || (outputSizeBytes != s.outputSizeBytes)) - { - throw new IllegalArgumentException("Incompatible parameters in provided SkeinEngine."); - } - copyIn(s); - } - - public int getOutputSize() - { - return outputSizeBytes; - } - - public int getBlockSize() - { - return threefish.getBlockSize(); - } - - /** - * Initialises the Skein engine with the provided parameters. See {@link SkeinParameters} for - * details on the parameterisation of the Skein hash function. - * - * @param params the parameters to apply to this engine, or <code>null</code> to use no parameters. - */ - public void init(SkeinParameters params) - { - this.chain = null; - this.key = null; - this.preMessageParameters = null; - this.postMessageParameters = null; - - if (params != null) - { - byte[] key = params.getKey(); - if (key.length < 16) - { - throw new IllegalArgumentException("Skein key must be at least 128 bits."); - } - initParams(params.getParameters()); - } - createInitialState(); - - // Initialise message block - ubiInit(PARAM_TYPE_MESSAGE); - } - - private void initParams(Hashtable parameters) - { - Enumeration keys = parameters.keys(); - final Vector pre = new Vector(); - final Vector post = new Vector(); - - while (keys.hasMoreElements()) - { - Integer type = (Integer)keys.nextElement(); - byte[] value = (byte[])parameters.get(type); - - if (type.intValue() == PARAM_TYPE_KEY) - { - this.key = value; - } - else if (type.intValue() < PARAM_TYPE_MESSAGE) - { - pre.addElement(new Parameter(type.intValue(), value)); - } - else - { - post.addElement(new Parameter(type.intValue(), value)); - } - } - preMessageParameters = new Parameter[pre.size()]; - pre.copyInto(preMessageParameters); - sort(preMessageParameters); - - postMessageParameters = new Parameter[post.size()]; - post.copyInto(postMessageParameters); - sort(postMessageParameters); - } - - private static void sort(Parameter[] params) - { - if (params == null) - { - return; - } - // Insertion sort, for Java 1.1 compatibility - for (int i = 1; i < params.length; i++) - { - Parameter param = params[i]; - int hole = i; - while (hole > 0 && param.getType() < params[hole - 1].getType()) - { - params[hole] = params[hole - 1]; - hole = hole - 1; - } - params[hole] = param; - } - } - - /** - * Calculate the initial (pre message block) chaining state. - */ - private void createInitialState() - { - long[] precalc = (long[])INITIAL_STATES.get(variantIdentifier(getBlockSize(), getOutputSize())); - if ((key == null) && (precalc != null)) - { - // Precalculated UBI(CFG) - chain = Arrays.clone(precalc); - } - else - { - // Blank initial state - chain = new long[getBlockSize() / 8]; - - // Process key block - if (key != null) - { - ubiComplete(SkeinParameters.PARAM_TYPE_KEY, key); - } - - // Process configuration block - ubiComplete(PARAM_TYPE_CONFIG, new Configuration(outputSizeBytes * 8).getBytes()); - } - - // Process additional pre-message parameters - if (preMessageParameters != null) - { - for (int i = 0; i < preMessageParameters.length; i++) - { - Parameter param = preMessageParameters[i]; - ubiComplete(param.getType(), param.getValue()); - } - } - initialState = Arrays.clone(chain); - } - - /** - * Reset the engine to the initial state (with the key and any pre-message parameters , ready to - * accept message input. - */ - public void reset() - { - System.arraycopy(initialState, 0, chain, 0, chain.length); - - ubiInit(PARAM_TYPE_MESSAGE); - } - - private void ubiComplete(int type, byte[] value) - { - ubiInit(type); - this.ubi.update(value, 0, value.length, chain); - ubiFinal(); - } - - private void ubiInit(int type) - { - this.ubi.reset(type); - } - - private void ubiFinal() - { - ubi.doFinal(chain); - } - - private void checkInitialised() - { - if (this.ubi == null) - { - throw new IllegalArgumentException("Skein engine is not initialised."); - } - } - - public void update(byte in) - { - singleByte[0] = in; - update(singleByte, 0, 1); - } - - public void update(byte[] in, int inOff, int len) - { - checkInitialised(); - ubi.update(in, inOff, len, chain); - } - - public int doFinal(byte[] out, int outOff) - { - checkInitialised(); - if (out.length < (outOff + outputSizeBytes)) - { - throw new DataLengthException("Output buffer is too short to hold output of " + outputSizeBytes + " bytes"); - } - - // Finalise message block - ubiFinal(); - - // Process additional post-message parameters - if (postMessageParameters != null) - { - for (int i = 0; i < postMessageParameters.length; i++) - { - Parameter param = postMessageParameters[i]; - ubiComplete(param.getType(), param.getValue()); - } - } - - // Perform the output transform - final int blockSize = getBlockSize(); - final int blocksRequired = ((outputSizeBytes + blockSize - 1) / blockSize); - for (int i = 0; i < blocksRequired; i++) - { - final int toWrite = Math.min(blockSize, outputSizeBytes - (i * blockSize)); - output(i, out, outOff + (i * blockSize), toWrite); - } - - reset(); - - return outputSizeBytes; - } - - private void output(long outputSequence, byte[] out, int outOff, int outputBytes) - { - byte[] currentBytes = new byte[8]; - ThreefishEngine.wordToBytes(outputSequence, currentBytes, 0); - - // Output is a sequence of UBI invocations all of which use and preserve the pre-output - // state - long[] outputWords = new long[chain.length]; - ubiInit(PARAM_TYPE_OUTPUT); - this.ubi.update(currentBytes, 0, currentBytes.length, outputWords); - ubi.doFinal(outputWords); - - final int wordsRequired = ((outputBytes + 8 - 1) / 8); - for (int i = 0; i < wordsRequired; i++) - { - int toWrite = Math.min(8, outputBytes - (i * 8)); - if (toWrite == 8) - { - ThreefishEngine.wordToBytes(outputWords[i], out, outOff + (i * 8)); - } - else - { - ThreefishEngine.wordToBytes(outputWords[i], currentBytes, 0); - System.arraycopy(currentBytes, 0, out, outOff + (i * 8), toWrite); - } - } - } - -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java deleted file mode 100644 index 76051c3f..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/encodings/PKCS1Encoding.java +++ /dev/null @@ -1,410 +0,0 @@ -package org.bouncycastle.crypto.encodings; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; - -/** - * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this - * depends on your application - see PKCS1 Version 2 for details. - */ -public class PKCS1Encoding - implements AsymmetricBlockCipher -{ - /** - * some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to - * work with one of these set the system property org.bouncycastle.pkcs1.strict to false. - * <p> - * The system property is checked during construction of the encoding object, it is set to - * true by default. - * </p> - */ - public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict"; - - private static final int HEADER_LENGTH = 10; - - private SecureRandom random; - private AsymmetricBlockCipher engine; - private boolean forEncryption; - private boolean forPrivateKey; - private boolean useStrictLength; - private int pLen = -1; - private byte[] fallback = null; - - /** - * Basic constructor. - * @param cipher - */ - public PKCS1Encoding( - AsymmetricBlockCipher cipher) - { - this.engine = cipher; - this.useStrictLength = useStrict(); - } - - /** - * Constructor for decryption with a fixed plaintext length. - * - * @param cipher The cipher to use for cryptographic operation. - * @param pLen Length of the expected plaintext. - */ - public PKCS1Encoding( - AsymmetricBlockCipher cipher, - int pLen) - { - this.engine = cipher; - this.useStrictLength = useStrict(); - this.pLen = pLen; - } - - /** - * Constructor for decryption with a fixed plaintext length and a fallback - * value that is returned, if the padding is incorrect. - * - * @param cipher - * The cipher to use for cryptographic operation. - * @param fallback - * The fallback value, we don't to a arraycopy here. - */ - public PKCS1Encoding( - AsymmetricBlockCipher cipher, - byte[] fallback) - { - this.engine = cipher; - this.useStrictLength = useStrict(); - this.fallback = fallback; - this.pLen = fallback.length; - } - - - - // - // for J2ME compatibility - // - private boolean useStrict() - { - // required if security manager has been installed. - String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY); - - return strict == null || strict.equals("true"); - } - - public AsymmetricBlockCipher getUnderlyingCipher() - { - return engine; - } - - public void init( - boolean forEncryption, - CipherParameters param) - { - AsymmetricKeyParameter kParam; - - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.random = rParam.getRandom(); - kParam = (AsymmetricKeyParameter)rParam.getParameters(); - } - else - { - this.random = new SecureRandom(); - kParam = (AsymmetricKeyParameter)param; - } - - engine.init(forEncryption, param); - - this.forPrivateKey = kParam.isPrivate(); - this.forEncryption = forEncryption; - } - - public int getInputBlockSize() - { - int baseBlockSize = engine.getInputBlockSize(); - - if (forEncryption) - { - return baseBlockSize - HEADER_LENGTH; - } - else - { - return baseBlockSize; - } - } - - public int getOutputBlockSize() - { - int baseBlockSize = engine.getOutputBlockSize(); - - if (forEncryption) - { - return baseBlockSize; - } - else - { - return baseBlockSize - HEADER_LENGTH; - } - } - - public byte[] processBlock( - byte[] in, - int inOff, - int inLen) - throws InvalidCipherTextException - { - if (forEncryption) - { - return encodeBlock(in, inOff, inLen); - } - else - { - return decodeBlock(in, inOff, inLen); - } - } - - private byte[] encodeBlock( - byte[] in, - int inOff, - int inLen) - throws InvalidCipherTextException - { - if (inLen > getInputBlockSize()) - { - throw new IllegalArgumentException("input data too large"); - } - - byte[] block = new byte[engine.getInputBlockSize()]; - - if (forPrivateKey) - { - block[0] = 0x01; // type code 1 - - for (int i = 1; i != block.length - inLen - 1; i++) - { - block[i] = (byte)0xFF; - } - } - else - { - random.nextBytes(block); // random fill - - block[0] = 0x02; // type code 2 - - // - // a zero byte marks the end of the padding, so all - // the pad bytes must be non-zero. - // - for (int i = 1; i != block.length - inLen - 1; i++) - { - while (block[i] == 0) - { - block[i] = (byte)random.nextInt(); - } - } - } - - block[block.length - inLen - 1] = 0x00; // mark the end of the padding - System.arraycopy(in, inOff, block, block.length - inLen, inLen); - - return engine.processBlock(block, 0, block.length); - } - - /** - * Checks if the argument is a correctly PKCS#1.5 encoded Plaintext - * for encryption. - * - * @param encoded The Plaintext. - * @param pLen Expected length of the plaintext. - * @return Either 0, if the encoding is correct, or -1, if it is incorrect. - */ - private static int checkPkcs1Encoding(byte[] encoded, int pLen) { - int correct = 0; - /* - * Check if the first two bytes are 0 2 - */ - correct |= (encoded[0] ^ 2); - - /* - * Now the padding check, check for no 0 byte in the padding - */ - int plen = encoded.length - ( - pLen /* Lenght of the PMS */ - + 1 /* Final 0-byte before PMS */ - ); - - for (int i = 1; i < plen; i++) { - int tmp = encoded[i]; - tmp |= tmp >> 1; - tmp |= tmp >> 2; - tmp |= tmp >> 4; - correct |= (tmp & 1) - 1; - } - - /* - * Make sure the padding ends with a 0 byte. - */ - correct |= encoded[encoded.length - (pLen +1)]; - - /* - * Return 0 or 1, depending on the result. - */ - correct |= correct >> 1; - correct |= correct >> 2; - correct |= correct >> 4; - return ~((correct & 1) - 1); - } - - - /** - * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct. - * - * @param in The encrypted block. - * @param inOff Offset in the encrypted block. - * @param inLen Length of the encrypted block. - * //@param pLen Length of the desired output. - * @return The plaintext without padding, or a random value if the padding was incorrect. - * - * @throws InvalidCipherTextException - */ - private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen) - throws InvalidCipherTextException - { - if (!forPrivateKey) - { - throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing"); - } - - byte[] block = engine.processBlock(in, inOff, inLen); - byte[] random = null; - if (this.fallback == null) - { - random = new byte[this.pLen]; - this.random.nextBytes(random); - } - else - { - random = fallback; - } - - /* - * TODO: This is a potential dangerous side channel. However, you can - * fix this by changing the RSA engine in a way, that it will always - * return blocks of the same length and prepend them with 0 bytes if - * needed. - */ - if (block.length < getOutputBlockSize()) - { - throw new InvalidCipherTextException("block truncated"); - } - - /* - * TODO: Potential side channel. Fix it by making the engine always - * return blocks of the correct length. - */ - if (useStrictLength && block.length != engine.getOutputBlockSize()) - { - throw new InvalidCipherTextException("block incorrect size"); - } - - /* - * Check the padding. - */ - int correct = PKCS1Encoding.checkPkcs1Encoding(block, this.pLen); - - /* - * Now, to a constant time constant memory copy of the decrypted value - * or the random value, depending on the validity of the padding. - */ - byte[] result = new byte[this.pLen]; - for (int i = 0; i < this.pLen; i++) - { - result[i] = (byte)((block[i + (block.length - pLen)] & (~correct)) | (random[i] & correct)); - } - - return result; - } - - /** - * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format. - */ - private byte[] decodeBlock( - byte[] in, - int inOff, - int inLen) - throws InvalidCipherTextException - { - /* - * If the length of the expected plaintext is known, we use a constant-time decryption. - * If the decryption fails, we return a random value. - */ - if (this.pLen != -1) { - return this.decodeBlockOrRandom(in, inOff, inLen); - } - - byte[] block = engine.processBlock(in, inOff, inLen); - - if (block.length < getOutputBlockSize()) - { - throw new InvalidCipherTextException("block truncated"); - } - - byte type = block[0]; - - if (forPrivateKey) - { - if (type != 2) - { - throw new InvalidCipherTextException("unknown block type"); - } - } - else - { - if (type != 1) - { - throw new InvalidCipherTextException("unknown block type"); - } - } - - if (useStrictLength && block.length != engine.getOutputBlockSize()) - { - throw new InvalidCipherTextException("block incorrect size"); - } - - // - // find and extract the message block. - // - int start; - - for (start = 1; start != block.length; start++) - { - byte pad = block[start]; - - if (pad == 0) - { - break; - } - if (type == 1 && pad != (byte)0xff) - { - throw new InvalidCipherTextException("block padding incorrect"); - } - } - - start++; // data should start at the next byte - - if (start > block.length || start < HEADER_LENGTH) - { - throw new InvalidCipherTextException("no data in block"); - } - - byte[] result = new byte[block.length - start]; - - System.arraycopy(block, start, result, 0, result.length); - - return result; - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/engines/NullEngine.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/engines/NullEngine.java deleted file mode 100644 index b5c74512..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/engines/NullEngine.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.bouncycastle.crypto.engines; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.OutputLengthException; - -/** - * The no-op engine that just copies bytes through, irrespective of whether encrypting and decrypting. - * Provided for the sake of completeness. - */ -public class NullEngine implements BlockCipher -{ - private boolean initialised; - protected static final int DEFAULT_BLOCK_SIZE = 1; - private int blockSize; - - /** - * Constructs a null engine with a block size of 1 byte. - */ - public NullEngine() - { - this(DEFAULT_BLOCK_SIZE); - } - - /** - * Constructs a null engine with a specific block size. - * - * @param blockSize the block size in bytes. - */ - public NullEngine(int blockSize) - { - this.blockSize = blockSize; - } - - /* (non-Javadoc) - * @see org.bouncycastle.crypto.BlockCipher#init(boolean, org.bouncycastle.crypto.CipherParameters) - */ - public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException - { - // we don't mind any parameters that may come in - this.initialised = true; - } - - /* (non-Javadoc) - * @see org.bouncycastle.crypto.BlockCipher#getAlgorithmName() - */ - public String getAlgorithmName() - { - return "Null"; - } - - /* (non-Javadoc) - * @see org.bouncycastle.crypto.BlockCipher#getBlockSize() - */ - public int getBlockSize() - { - return blockSize; - } - - /* (non-Javadoc) - * @see org.bouncycastle.crypto.BlockCipher#processBlock(byte[], int, byte[], int) - */ - public int processBlock(byte[] in, int inOff, byte[] out, int outOff) - throws DataLengthException, IllegalStateException - { - if (!initialised) - { - throw new IllegalStateException("Null engine not initialised"); - } - if ((inOff + blockSize) > in.length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + blockSize) > out.length) - { - throw new OutputLengthException("output buffer too short"); - } - - for (int i = 0; i < blockSize; ++i) - { - out[outOff + i] = in[inOff + i]; - } - - return blockSize; - } - - /* (non-Javadoc) - * @see org.bouncycastle.crypto.BlockCipher#reset() - */ - public void reset() - { - // nothing needs to be done - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java deleted file mode 100644 index 3cbe9182..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.bouncycastle.crypto.params; - -import java.security.SecureRandom; - -public class DSAParameterGenerationParameters -{ - public static final int DIGITAL_SIGNATURE_USAGE = 1; - public static final int KEY_ESTABLISHMENT_USAGE = 2; - - private int l; - private int n; - private int usageIndex; - private int certainty; - private SecureRandom random; - - /** - * Construct without a usage index, this will do a random construction of G. - * - * @param L desired length of prime P in bits (the effective key size). - * @param N desired length of prime Q in bits. - * @param certainty certainty level for prime number generation. - * @param random the source of randomness to use. - */ - public DSAParameterGenerationParameters( - int L, - int N, - int certainty, - SecureRandom random) - { - this(L, N, certainty, random, -1); - } - - /** - * Construct for a specific usage index - this has the effect of using verifiable canonical generation of G. - * - * @param L desired length of prime P in bits (the effective key size). - * @param N desired length of prime Q in bits. - * @param certainty certainty level for prime number generation. - * @param random the source of randomness to use. - * @param usageIndex a valid usage index. - */ - public DSAParameterGenerationParameters( - int L, - int N, - int certainty, - SecureRandom random, - int usageIndex) - { - this.l = L; - this.n = N; - this.certainty = certainty; - this.usageIndex = usageIndex; - this.random = random; - } - - public int getL() - { - return l; - } - - public int getN() - { - return n; - } - - public int getCertainty() - { - return certainty; - } - - public SecureRandom getRandom() - { - return random; - } - - public int getUsageIndex() - { - return usageIndex; - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/params/HKDFParameters.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/params/HKDFParameters.java deleted file mode 100644 index 0f41955a..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/params/HKDFParameters.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.bouncycastle.crypto.params; - -import org.bouncycastle.crypto.DerivationParameters; -import org.bouncycastle.util.Arrays; - -/** - * Parameter class for the HKDFBytesGenerator class. - */ -public class HKDFParameters - implements DerivationParameters -{ - private byte[] ikm; - private boolean skipExpand; - private byte[] salt; - private byte[] info; - - private HKDFParameters(final byte[] ikm, final boolean skip, - final byte[] salt, final byte[] info) - { - if (ikm == null) - { - throw new IllegalArgumentException( - "IKM (input keying material) should not be null"); - } - - this.ikm = Arrays.clone(ikm); - - this.skipExpand = skip; - - if (salt == null || salt.length == 0) - { - this.salt = null; - } - else - { - this.salt = Arrays.clone(salt); - } - - if (info == null) - { - this.info = new byte[0]; - } - else - { - this.info = Arrays.clone(info); - } - } - - /** - * Generates parameters for HKDF, specifying both the optional salt and - * optional info. Step 1: Extract won't be skipped. - * - * @param ikm the input keying material or seed - * @param salt the salt to use, may be null for a salt for hashLen zeros - * @param info the info to use, may be null for an info field of zero bytes - */ - public HKDFParameters(final byte[] ikm, final byte[] salt, final byte[] info) - { - this(ikm, false, salt, info); - } - - /** - * Factory method that makes the HKDF skip the extract part of the key - * derivation function. - * - * @param ikm the input keying material or seed, directly used for step 2: - * Expand - * @param info the info to use, may be null for an info field of zero bytes - * @return HKDFParameters that makes the implementation skip step 1 - */ - public static HKDFParameters skipExtractParameters(final byte[] ikm, - final byte[] info) - { - - return new HKDFParameters(ikm, true, null, info); - } - - public static HKDFParameters defaultParameters(final byte[] ikm) - { - return new HKDFParameters(ikm, false, null, null); - } - - /** - * Returns the input keying material or seed. - * - * @return the keying material - */ - public byte[] getIKM() - { - return Arrays.clone(ikm); - } - - /** - * Returns if step 1: extract has to be skipped or not - * - * @return true for skipping, false for no skipping of step 1 - */ - public boolean skipExtract() - { - return skipExpand; - } - - /** - * Returns the salt, or null if the salt should be generated as a byte array - * of HashLen zeros. - * - * @return the salt, or null - */ - public byte[] getSalt() - { - return Arrays.clone(salt); - } - - /** - * Returns the info field, which may be empty (null is converted to empty). - * - * @return the info field, never null - */ - public byte[] getInfo() - { - return Arrays.clone(info); - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/prng/BasicEntropySourceProvider.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/prng/BasicEntropySourceProvider.java deleted file mode 100644 index ded87a71..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/prng/BasicEntropySourceProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.bouncycastle.crypto.prng; - -import java.security.SecureRandom; - -/** - * An EntropySourceProvider where entropy generation is based on a SecureRandom output using SecureRandom.generateSeed(). - */ -public class BasicEntropySourceProvider - implements EntropySourceProvider -{ - private SecureRandom _sr; - private boolean _predictionResistant; - - /** - * Create a entropy source provider based on the passed in SecureRandom. - * - * @param random the SecureRandom to base EntropySource construction on. - * @param isPredictionResistant boolean indicating if the SecureRandom is based on prediction resistant entropy or not (true if it is). - */ - public BasicEntropySourceProvider(SecureRandom random, boolean isPredictionResistant) - { - _sr = random; - _predictionResistant = isPredictionResistant; - } - - /** - * Return an entropy source that will create bitsRequired bits of entropy on - * each invocation of getEntropy(). - * - * @param bitsRequired size (in bits) of entropy to be created by the provided source. - * @return an EntropySource that generates bitsRequired bits of entropy on each call to its getEntropy() method. - */ - public EntropySource get(final int bitsRequired) - { - return new EntropySource() - { - public boolean isPredictionResistant() - { - return _predictionResistant; - } - - public byte[] getEntropy() - { - byte[] rv = new byte[(bitsRequired + 7) / 8]; - - _sr.nextBytes(rv); - - return rv; - } - - public int entropySize() - { - return bitsRequired; - } - }; - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java deleted file mode 100644 index 666a8541..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java +++ /dev/null @@ -1,289 +0,0 @@ -package org.bouncycastle.crypto.prng; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG; -import org.bouncycastle.crypto.prng.drbg.DualECPoints; -import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG; -import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG; -import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG; -import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; - -/** - * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG). - */ -public class SP800SecureRandomBuilder -{ - private SecureRandom random; - private EntropySourceProvider entropySourceProvider; - - private byte[] personalizationString; - private int securityStrength = 256; - private int entropyBitsRequired = 256; - - /** - * Basic constructor, creates a builder using an EntropySourceProvider based on the default SecureRandom with - * predictionResistant set to false. - * <p> - * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if - * the default SecureRandom does for its generateSeed() call. - * </p> - */ - public SP800SecureRandomBuilder() - { - this(new SecureRandom(), false); - } - - /** - * Construct a builder with an EntropySourceProvider based on the passed in SecureRandom and the passed in value - * for prediction resistance. - * <p> - * Any SecureRandom created from a builder constructed like this will make use of input passed to SecureRandom.setSeed() if - * the passed in SecureRandom does for its generateSeed() call. - * </p> - * @param entropySource - * @param predictionResistant - */ - public SP800SecureRandomBuilder(SecureRandom entropySource, boolean predictionResistant) - { - this.random = entropySource; - this.entropySourceProvider = new BasicEntropySourceProvider(random, predictionResistant); - } - - /** - * Create a builder which makes creates the SecureRandom objects from a specified entropy source provider. - * <p> - * <b>Note:</b> If this constructor is used any calls to setSeed() in the resulting SecureRandom will be ignored. - * </p> - * @param entropySourceProvider a provider of EntropySource objects. - */ - public SP800SecureRandomBuilder(EntropySourceProvider entropySourceProvider) - { - this.random = null; - this.entropySourceProvider = entropySourceProvider; - } - - /** - * Set the personalization string for DRBG SecureRandoms created by this builder - * @param personalizationString the personalisation string for the underlying DRBG. - * @return the current builder. - */ - public SP800SecureRandomBuilder setPersonalizationString(byte[] personalizationString) - { - this.personalizationString = personalizationString; - - return this; - } - - /** - * Set the security strength required for DRBGs used in building SecureRandom objects. - * - * @param securityStrength the security strength (in bits) - * @return the current builder. - */ - public SP800SecureRandomBuilder setSecurityStrength(int securityStrength) - { - this.securityStrength = securityStrength; - - return this; - } - - /** - * Set the amount of entropy bits required for seeding and reseeding DRBGs used in building SecureRandom objects. - * - * @param entropyBitsRequired the number of bits of entropy to be requested from the entropy source on each seed/reseed. - * @return the current builder. - */ - public SP800SecureRandomBuilder setEntropyBitsRequired(int entropyBitsRequired) - { - this.entropyBitsRequired = entropyBitsRequired; - - return this; - } - - /** - * Build a SecureRandom based on a SP 800-90A Hash DRBG. - * - * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. - * @param nonce nonce value to use in DRBG construction. - * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. - * @return a SecureRandom supported by a Hash DRBG. - */ - public SP800SecureRandom buildHash(Digest digest, byte[] nonce, boolean predictionResistant) - { - return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HashDRBGProvider(digest, nonce, personalizationString, securityStrength), predictionResistant); - } - - /** - * Build a SecureRandom based on a SP 800-90A CTR DRBG. - * - * @param cipher the block cipher to base the DRBG on. - * @param keySizeInBits key size in bits to be used with the block cipher. - * @param nonce nonce value to use in DRBG construction. - * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. - * @return a SecureRandom supported by a CTR DRBG. - */ - public SP800SecureRandom buildCTR(BlockCipher cipher, int keySizeInBits, byte[] nonce, boolean predictionResistant) - { - return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new CTRDRBGProvider(cipher, keySizeInBits, nonce, personalizationString, securityStrength), predictionResistant); - } - - /** - * Build a SecureRandom based on a SP 800-90A HMAC DRBG. - * - * @param hMac HMAC algorithm to use in the DRBG underneath the SecureRandom. - * @param nonce nonce value to use in DRBG construction. - * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. - * @return a SecureRandom supported by a HMAC DRBG. - */ - public SP800SecureRandom buildHMAC(Mac hMac, byte[] nonce, boolean predictionResistant) - { - return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new HMacDRBGProvider(hMac, nonce, personalizationString, securityStrength), predictionResistant); - } - - /** - * Build a SecureRandom based on a SP 800-90A Dual EC DRBG. - * - * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. - * @param nonce nonce value to use in DRBG construction. - * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. - * @return a SecureRandom supported by a Dual EC DRBG. - */ - public SP800SecureRandom buildDualEC(Digest digest, byte[] nonce, boolean predictionResistant) - { - return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new DualECDRBGProvider(digest, nonce, personalizationString, securityStrength), predictionResistant); - } - - /** - * Build a SecureRandom based on a SP 800-90A Dual EC DRBG. - * - * @param pointSet an array of DualECPoints to use for DRB generation. - * @param digest digest algorithm to use in the DRBG underneath the SecureRandom. - * @param nonce nonce value to use in DRBG construction. - * @param predictionResistant specify whether the underlying DRBG in the resulting SecureRandom should reseed on each request for bytes. - * @return a SecureRandom supported by a Dual EC DRBG. - */ - public SP800SecureRandom buildDualEC(DualECPoints[] pointSet, Digest digest, byte[] nonce, boolean predictionResistant) - { - return new SP800SecureRandom(random, entropySourceProvider.get(entropyBitsRequired), new ConfigurableDualECDRBGProvider(pointSet, digest, nonce, personalizationString, securityStrength), predictionResistant); - } - - private static class HashDRBGProvider - implements DRBGProvider - { - private final Digest digest; - private final byte[] nonce; - private final byte[] personalizationString; - private final int securityStrength; - - public HashDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) - { - this.digest = digest; - this.nonce = nonce; - this.personalizationString = personalizationString; - this.securityStrength = securityStrength; - } - - public SP80090DRBG get(EntropySource entropySource) - { - return new HashSP800DRBG(digest, securityStrength, entropySource, personalizationString, nonce); - } - } - - private static class DualECDRBGProvider - implements DRBGProvider - { - private final Digest digest; - private final byte[] nonce; - private final byte[] personalizationString; - private final int securityStrength; - - public DualECDRBGProvider(Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) - { - this.digest = digest; - this.nonce = nonce; - this.personalizationString = personalizationString; - this.securityStrength = securityStrength; - } - - public SP80090DRBG get(EntropySource entropySource) - { - return new DualECSP800DRBG(digest, securityStrength, entropySource, personalizationString, nonce); - } - } - - private static class ConfigurableDualECDRBGProvider - implements DRBGProvider - { - private final DualECPoints[] pointSet; - private final Digest digest; - private final byte[] nonce; - private final byte[] personalizationString; - private final int securityStrength; - - public ConfigurableDualECDRBGProvider(DualECPoints[] pointSet, Digest digest, byte[] nonce, byte[] personalizationString, int securityStrength) - { - this.pointSet = new DualECPoints[pointSet.length]; - System.arraycopy(pointSet, 0, this.pointSet, 0, pointSet.length); - this.digest = digest; - this.nonce = nonce; - this.personalizationString = personalizationString; - this.securityStrength = securityStrength; - } - - public SP80090DRBG get(EntropySource entropySource) - { - return new DualECSP800DRBG(pointSet, digest, securityStrength, entropySource, personalizationString, nonce); - } - } - - private static class HMacDRBGProvider - implements DRBGProvider - { - private final Mac hMac; - private final byte[] nonce; - private final byte[] personalizationString; - private final int securityStrength; - - public HMacDRBGProvider(Mac hMac, byte[] nonce, byte[] personalizationString, int securityStrength) - { - this.hMac = hMac; - this.nonce = nonce; - this.personalizationString = personalizationString; - this.securityStrength = securityStrength; - } - - public SP80090DRBG get(EntropySource entropySource) - { - return new HMacSP800DRBG(hMac, securityStrength, entropySource, personalizationString, nonce); - } - } - - private static class CTRDRBGProvider - implements DRBGProvider - { - - private final BlockCipher blockCipher; - private final int keySizeInBits; - private final byte[] nonce; - private final byte[] personalizationString; - private final int securityStrength; - - public CTRDRBGProvider(BlockCipher blockCipher, int keySizeInBits, byte[] nonce, byte[] personalizationString, int securityStrength) - { - this.blockCipher = blockCipher; - this.keySizeInBits = keySizeInBits; - this.nonce = nonce; - this.personalizationString = personalizationString; - this.securityStrength = securityStrength; - } - - public SP80090DRBG get(EntropySource entropySource) - { - return new CTRSP800DRBG(blockCipher, keySizeInBits, securityStrength, entropySource, personalizationString, nonce); - } - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/signers/RSADigestSigner.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/signers/RSADigestSigner.java deleted file mode 100644 index f15e4047..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/signers/RSADigestSigner.java +++ /dev/null @@ -1,238 +0,0 @@ -package org.bouncycastle.crypto.signers; - -import java.io.IOException; -import java.util.Hashtable; - -import org.bouncycastle.asn1.ASN1Encoding; -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x509.DigestInfo; -import org.bouncycastle.asn1.x509.X509ObjectIdentifiers; -import org.bouncycastle.crypto.AsymmetricBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.Signer; -import org.bouncycastle.crypto.encodings.PKCS1Encoding; -import org.bouncycastle.crypto.engines.RSABlindedEngine; -import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.util.Arrays; - -public class RSADigestSigner - implements Signer -{ - private final AsymmetricBlockCipher rsaEngine = new PKCS1Encoding(new RSABlindedEngine()); - private AlgorithmIdentifier algId; - private Digest digest; - private boolean forSigning; - - private static final Hashtable oidMap = new Hashtable(); - - /* - * Load OID table. - */ - static - { - oidMap.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128); - oidMap.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160); - oidMap.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256); - - oidMap.put("SHA-1", X509ObjectIdentifiers.id_SHA1); - oidMap.put("SHA-224", NISTObjectIdentifiers.id_sha224); - oidMap.put("SHA-256", NISTObjectIdentifiers.id_sha256); - oidMap.put("SHA-384", NISTObjectIdentifiers.id_sha384); - oidMap.put("SHA-512", NISTObjectIdentifiers.id_sha512); - - oidMap.put("MD2", PKCSObjectIdentifiers.md2); - oidMap.put("MD4", PKCSObjectIdentifiers.md4); - oidMap.put("MD5", PKCSObjectIdentifiers.md5); - } - - public RSADigestSigner( - Digest digest) - { - this(digest, (ASN1ObjectIdentifier)oidMap.get(digest.getAlgorithmName())); - } - - public RSADigestSigner( - Digest digest, - ASN1ObjectIdentifier digestOid) - { - this.digest = digest; - this.algId = new AlgorithmIdentifier(digestOid, DERNull.INSTANCE); - } - - /** - * @deprecated - */ - public String getAlgorithmName() - { - return digest.getAlgorithmName() + "withRSA"; - } - - /** - * initialise the signer for signing or verification. - * - * @param forSigning - * true if for signing, false otherwise - * @param parameters - * necessary parameters. - */ - public void init( - boolean forSigning, - CipherParameters parameters) - { - this.forSigning = forSigning; - AsymmetricKeyParameter k; - - if (parameters instanceof ParametersWithRandom) - { - k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters(); - } - else - { - k = (AsymmetricKeyParameter)parameters; - } - - if (forSigning && !k.isPrivate()) - { - throw new IllegalArgumentException("signing requires private key"); - } - - if (!forSigning && k.isPrivate()) - { - throw new IllegalArgumentException("verification requires public key"); - } - - reset(); - - rsaEngine.init(forSigning, parameters); - } - - /** - * update the internal digest with the byte b - */ - public void update( - byte input) - { - digest.update(input); - } - - /** - * update the internal digest with the byte array in - */ - public void update( - byte[] input, - int inOff, - int length) - { - digest.update(input, inOff, length); - } - - /** - * Generate a signature for the message we've been loaded with using the key - * we were initialised with. - */ - public byte[] generateSignature() - throws CryptoException, DataLengthException - { - if (!forSigning) - { - throw new IllegalStateException("RSADigestSigner not initialised for signature generation."); - } - - byte[] hash = new byte[digest.getDigestSize()]; - digest.doFinal(hash, 0); - - try - { - byte[] data = derEncode(hash); - return rsaEngine.processBlock(data, 0, data.length); - } - catch (IOException e) - { - throw new CryptoException("unable to encode signature: " + e.getMessage(), e); - } - } - - /** - * return true if the internal state represents the signature described in - * the passed in array. - */ - public boolean verifySignature( - byte[] signature) - { - if (forSigning) - { - throw new IllegalStateException("RSADigestSigner not initialised for verification"); - } - - byte[] hash = new byte[digest.getDigestSize()]; - - digest.doFinal(hash, 0); - - byte[] sig; - byte[] expected; - - try - { - sig = rsaEngine.processBlock(signature, 0, signature.length); - expected = derEncode(hash); - } - catch (Exception e) - { - return false; - } - - if (sig.length == expected.length) - { - return Arrays.constantTimeAreEqual(sig, expected); - } - else if (sig.length == expected.length - 2) // NULL left out - { - int sigOffset = sig.length - hash.length - 2; - int expectedOffset = expected.length - hash.length - 2; - - expected[1] -= 2; // adjust lengths - expected[3] -= 2; - - int nonEqual = 0; - - for (int i = 0; i < hash.length; i++) - { - nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]); - } - - for (int i = 0; i < sigOffset; i++) - { - nonEqual |= (sig[i] ^ expected[i]); // check header less NULL - } - - return nonEqual == 0; - } - else - { - return false; - } - } - - public void reset() - { - digest.reset(); - } - - private byte[] derEncode( - byte[] hash) - throws IOException - { - DigestInfo dInfo = new DigestInfo(algId, hash); - - return dInfo.getEncoded(ASN1Encoding.DER); - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/AbstractTlsContext.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/AbstractTlsContext.java deleted file mode 100644 index b8153b06..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/AbstractTlsContext.java +++ /dev/null @@ -1,135 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.security.SecureRandom; - -import org.bouncycastle.crypto.prng.DigestRandomGenerator; -import org.bouncycastle.crypto.prng.RandomGenerator; -import org.bouncycastle.util.Times; - -abstract class AbstractTlsContext - implements TlsContext -{ - private static long counter = Times.nanoTime(); - - private synchronized static long nextCounterValue() - { - return ++counter; - } - - private RandomGenerator nonceRandom; - private SecureRandom secureRandom; - private SecurityParameters securityParameters; - - private ProtocolVersion clientVersion = null; - private ProtocolVersion serverVersion = null; - private TlsSession session = null; - private Object userObject = null; - - AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters) - { - secureRandom.setSeed(nextCounterValue()); - secureRandom.setSeed(Times.nanoTime()); - - this.nonceRandom = new DigestRandomGenerator(TlsUtils.createHash(HashAlgorithm.sha256)); - byte[] nonceSeed = new byte[32]; - secureRandom.nextBytes(nonceSeed); - this.nonceRandom.addSeedMaterial(nonceSeed); - - this.secureRandom = secureRandom; - this.securityParameters = securityParameters; - } - - public RandomGenerator getNonceRandomGenerator() - { - return nonceRandom; - } - - public SecureRandom getSecureRandom() - { - return secureRandom; - } - - public SecurityParameters getSecurityParameters() - { - return securityParameters; - } - - public ProtocolVersion getClientVersion() - { - return clientVersion; - } - - void setClientVersion(ProtocolVersion clientVersion) - { - this.clientVersion = clientVersion; - } - - public ProtocolVersion getServerVersion() - { - return serverVersion; - } - - void setServerVersion(ProtocolVersion serverVersion) - { - this.serverVersion = serverVersion; - } - - public TlsSession getResumableSession() - { - return session; - } - - void setResumableSession(TlsSession session) - { - this.session = session; - } - - public Object getUserObject() - { - return userObject; - } - - public void setUserObject(Object userObject) - { - this.userObject = userObject; - } - - public byte[] exportKeyingMaterial(String asciiLabel, byte[] context_value, int length) - { - if (context_value != null && !TlsUtils.isValidUint16(context_value.length)) - { - throw new IllegalArgumentException("'context_value' must have length less than 2^16 (or be null)"); - } - - SecurityParameters sp = getSecurityParameters(); - byte[] cr = sp.getClientRandom(), sr = sp.getServerRandom(); - - int seedLength = cr.length + sr.length; - if (context_value != null) - { - seedLength += (2 + context_value.length); - } - - byte[] seed = new byte[seedLength]; - int seedPos = 0; - - System.arraycopy(cr, 0, seed, seedPos, cr.length); - seedPos += cr.length; - System.arraycopy(sr, 0, seed, seedPos, sr.length); - seedPos += sr.length; - if (context_value != null) - { - TlsUtils.writeUint16(context_value.length, seed, seedPos); - seedPos += 2; - System.arraycopy(context_value, 0, seed, seedPos, context_value.length); - seedPos += context_value.length; - } - - if (seedPos != seedLength) - { - throw new IllegalStateException("error in calculation of seed for export"); - } - - return TlsUtils.PRF(this, sp.getMasterSecret(), asciiLabel, seed, length); - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/DTLSReassembler.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/DTLSReassembler.java deleted file mode 100644 index 2d3cf267..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/DTLSReassembler.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.util.Vector; - -class DTLSReassembler -{ - - private short msg_type; - private byte[] body; - - private Vector missing = new Vector(); - - DTLSReassembler(short msg_type, int length) - { - this.msg_type = msg_type; - this.body = new byte[length]; - this.missing.addElement(new Range(0, length)); - } - - short getType() - { - return msg_type; - } - - byte[] getBodyIfComplete() - { - return missing.isEmpty() ? body : null; - } - - void contributeFragment(short msg_type, int length, byte[] buf, int off, int fragment_offset, - int fragment_length) - { - - int fragment_end = fragment_offset + fragment_length; - - if (this.msg_type != msg_type || this.body.length != length || fragment_end > length) - { - return; - } - - if (fragment_length == 0) - { - // NOTE: Empty messages still require an empty fragment to complete it - if (fragment_offset == 0 && !missing.isEmpty()) - { - Range firstRange = (Range)missing.firstElement(); - if (firstRange.getEnd() == 0) - { - missing.removeElementAt(0); - } - } - return; - } - - for (int i = 0; i < missing.size(); ++i) - { - Range range = (Range)missing.elementAt(i); - if (range.getStart() >= fragment_end) - { - break; - } - if (range.getEnd() > fragment_offset) - { - - int copyStart = Math.max(range.getStart(), fragment_offset); - int copyEnd = Math.min(range.getEnd(), fragment_end); - int copyLength = copyEnd - copyStart; - - System.arraycopy(buf, off + copyStart - fragment_offset, body, copyStart, - copyLength); - - if (copyStart == range.getStart()) - { - if (copyEnd == range.getEnd()) - { - missing.removeElementAt(i--); - } - else - { - range.setStart(copyEnd); - } - } - else - { - if (copyEnd == range.getEnd()) - { - range.setEnd(copyStart); - } - else - { - missing.insertElementAt(new Range(copyEnd, range.getEnd()), ++i); - range.setEnd(copyStart); - } - } - } - } - } - - void reset() - { - this.missing.removeAllElements(); - this.missing.addElement(new Range(0, body.length)); - } - - private static class Range - { - - private int start, end; - - Range(int start, int end) - { - this.start = start; - this.end = end; - } - - public int getStart() - { - return start; - } - - public void setStart(int start) - { - this.start = start; - } - - public int getEnd() - { - return end; - } - - public void setEnd(int end) - { - this.end = end; - } - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java deleted file mode 100644 index af694ac9..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/DTLSReliableHandshake.java +++ /dev/null @@ -1,457 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.util.Integers; - -class DTLSReliableHandshake -{ - private final static int MAX_RECEIVE_AHEAD = 10; - - private DTLSRecordLayer recordLayer; - - private TlsHandshakeHash handshakeHash; - - private Hashtable currentInboundFlight = new Hashtable(); - private Hashtable previousInboundFlight = null; - private Vector outboundFlight = new Vector(); - private boolean sending = true; - - private int message_seq = 0, next_receive_seq = 0; - - DTLSReliableHandshake(TlsContext context, DTLSRecordLayer transport) - { - this.recordLayer = transport; - this.handshakeHash = new DeferredHash(); - this.handshakeHash.init(context); - } - - void notifyHelloComplete() - { - this.handshakeHash = handshakeHash.notifyPRFDetermined(); - } - - TlsHandshakeHash getHandshakeHash() - { - return handshakeHash; - } - - TlsHandshakeHash prepareToFinish() - { - TlsHandshakeHash result = handshakeHash; - this.handshakeHash = handshakeHash.stopTracking(); - return result; - } - - void sendMessage(short msg_type, byte[] body) - throws IOException - { - TlsUtils.checkUint24(body.length); - - if (!sending) - { - checkInboundFlight(); - sending = true; - outboundFlight.removeAllElements(); - } - - Message message = new Message(message_seq++, msg_type, body); - - outboundFlight.addElement(message); - - writeMessage(message); - updateHandshakeMessagesDigest(message); - } - - byte[] receiveMessageBody(short msg_type) - throws IOException - { - Message message = receiveMessage(); - if (message.getType() != msg_type) - { - throw new TlsFatalAlert(AlertDescription.unexpected_message); - } - - return message.getBody(); - } - - Message receiveMessage() - throws IOException - { - if (sending) - { - sending = false; - prepareInboundFlight(); - } - - // Check if we already have the next message waiting - { - DTLSReassembler next = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(next_receive_seq)); - if (next != null) - { - byte[] body = next.getBodyIfComplete(); - if (body != null) - { - previousInboundFlight = null; - return updateHandshakeMessagesDigest(new Message(next_receive_seq++, next.getType(), body)); - } - } - } - - byte[] buf = null; - - // TODO Check the conditions under which we should reset this - int readTimeoutMillis = 1000; - - for (; ; ) - { - int receiveLimit = recordLayer.getReceiveLimit(); - if (buf == null || buf.length < receiveLimit) - { - buf = new byte[receiveLimit]; - } - - // TODO Handle records containing multiple handshake messages - - try - { - for (; ; ) - { - int received = recordLayer.receive(buf, 0, receiveLimit, readTimeoutMillis); - if (received < 0) - { - break; - } - if (received < 12) - { - continue; - } - int fragment_length = TlsUtils.readUint24(buf, 9); - if (received != (fragment_length + 12)) - { - continue; - } - int seq = TlsUtils.readUint16(buf, 4); - if (seq > (next_receive_seq + MAX_RECEIVE_AHEAD)) - { - continue; - } - short msg_type = TlsUtils.readUint8(buf, 0); - int length = TlsUtils.readUint24(buf, 1); - int fragment_offset = TlsUtils.readUint24(buf, 6); - if (fragment_offset + fragment_length > length) - { - continue; - } - - if (seq < next_receive_seq) - { - /* - * NOTE: If we receive the previous flight of incoming messages in full - * again, retransmit our last flight - */ - if (previousInboundFlight != null) - { - DTLSReassembler reassembler = (DTLSReassembler)previousInboundFlight.get(Integers - .valueOf(seq)); - if (reassembler != null) - { - - reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, - fragment_length); - - if (checkAll(previousInboundFlight)) - { - - resendOutboundFlight(); - - /* - * TODO[DTLS] implementations SHOULD back off handshake packet - * size during the retransmit backoff. - */ - readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); - - resetAll(previousInboundFlight); - } - } - } - } - else - { - - DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); - if (reassembler == null) - { - reassembler = new DTLSReassembler(msg_type, length); - currentInboundFlight.put(Integers.valueOf(seq), reassembler); - } - - reassembler.contributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); - - if (seq == next_receive_seq) - { - byte[] body = reassembler.getBodyIfComplete(); - if (body != null) - { - previousInboundFlight = null; - return updateHandshakeMessagesDigest(new Message(next_receive_seq++, - reassembler.getType(), body)); - } - } - } - } - } - catch (IOException e) - { - // NOTE: Assume this is a timeout for the moment - } - - resendOutboundFlight(); - - /* - * TODO[DTLS] implementations SHOULD back off handshake packet size during the - * retransmit backoff. - */ - readTimeoutMillis = Math.min(readTimeoutMillis * 2, 60000); - } - } - - void finish() - { - DTLSHandshakeRetransmit retransmit = null; - if (!sending) - { - checkInboundFlight(); - } - else if (currentInboundFlight != null) - { - /* - * RFC 6347 4.2.4. In addition, for at least twice the default MSL defined for [TCP], - * when in the FINISHED state, the node that transmits the last flight (the server in an - * ordinary handshake or the client in a resumed handshake) MUST respond to a retransmit - * of the peer's last flight with a retransmit of the last flight. - */ - retransmit = new DTLSHandshakeRetransmit() - { - public void receivedHandshakeRecord(int epoch, byte[] buf, int off, int len) - throws IOException - { - /* - * TODO Need to handle the case where the previous inbound flight contains - * messages from two epochs. - */ - if (len < 12) - { - return; - } - int fragment_length = TlsUtils.readUint24(buf, off + 9); - if (len != (fragment_length + 12)) - { - return; - } - int seq = TlsUtils.readUint16(buf, off + 4); - if (seq >= next_receive_seq) - { - return; - } - - short msg_type = TlsUtils.readUint8(buf, off); - - // TODO This is a hack that only works until we try to support renegotiation - int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; - if (epoch != expectedEpoch) - { - return; - } - - int length = TlsUtils.readUint24(buf, off + 1); - int fragment_offset = TlsUtils.readUint24(buf, off + 6); - if (fragment_offset + fragment_length > length) - { - return; - } - - DTLSReassembler reassembler = (DTLSReassembler)currentInboundFlight.get(Integers.valueOf(seq)); - if (reassembler != null) - { - reassembler.contributeFragment(msg_type, length, buf, off + 12, fragment_offset, - fragment_length); - if (checkAll(currentInboundFlight)) - { - resendOutboundFlight(); - resetAll(currentInboundFlight); - } - } - } - }; - } - - recordLayer.handshakeSuccessful(retransmit); - } - - void resetHandshakeMessagesDigest() - { - handshakeHash.reset(); - } - - /** - * Check that there are no "extra" messages left in the current inbound flight - */ - private void checkInboundFlight() - { - Enumeration e = currentInboundFlight.keys(); - while (e.hasMoreElements()) - { - Integer key = (Integer)e.nextElement(); - if (key.intValue() >= next_receive_seq) - { - // TODO Should this be considered an error? - } - } - } - - private void prepareInboundFlight() - { - resetAll(currentInboundFlight); - previousInboundFlight = currentInboundFlight; - currentInboundFlight = new Hashtable(); - } - - private void resendOutboundFlight() - throws IOException - { - recordLayer.resetWriteEpoch(); - for (int i = 0; i < outboundFlight.size(); ++i) - { - writeMessage((Message)outboundFlight.elementAt(i)); - } - } - - private Message updateHandshakeMessagesDigest(Message message) - throws IOException - { - if (message.getType() != HandshakeType.hello_request) - { - byte[] body = message.getBody(); - byte[] buf = new byte[12]; - TlsUtils.writeUint8(message.getType(), buf, 0); - TlsUtils.writeUint24(body.length, buf, 1); - TlsUtils.writeUint16(message.getSeq(), buf, 4); - TlsUtils.writeUint24(0, buf, 6); - TlsUtils.writeUint24(body.length, buf, 9); - handshakeHash.update(buf, 0, buf.length); - handshakeHash.update(body, 0, body.length); - } - return message; - } - - private void writeMessage(Message message) - throws IOException - { - int sendLimit = recordLayer.getSendLimit(); - int fragmentLimit = sendLimit - 12; - - // TODO Support a higher minimum fragment size? - if (fragmentLimit < 1) - { - // TODO Should we be throwing an exception here? - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - int length = message.getBody().length; - - // NOTE: Must still send a fragment if body is empty - int fragment_offset = 0; - do - { - int fragment_length = Math.min(length - fragment_offset, fragmentLimit); - writeHandshakeFragment(message, fragment_offset, fragment_length); - fragment_offset += fragment_length; - } - while (fragment_offset < length); - } - - private void writeHandshakeFragment(Message message, int fragment_offset, int fragment_length) - throws IOException - { - RecordLayerBuffer fragment = new RecordLayerBuffer(12 + fragment_length); - TlsUtils.writeUint8(message.getType(), fragment); - TlsUtils.writeUint24(message.getBody().length, fragment); - TlsUtils.writeUint16(message.getSeq(), fragment); - TlsUtils.writeUint24(fragment_offset, fragment); - TlsUtils.writeUint24(fragment_length, fragment); - fragment.write(message.getBody(), fragment_offset, fragment_length); - - fragment.sendToRecordLayer(recordLayer); - } - - private static boolean checkAll(Hashtable inboundFlight) - { - Enumeration e = inboundFlight.elements(); - while (e.hasMoreElements()) - { - if (((DTLSReassembler)e.nextElement()).getBodyIfComplete() == null) - { - return false; - } - } - return true; - } - - private static void resetAll(Hashtable inboundFlight) - { - Enumeration e = inboundFlight.elements(); - while (e.hasMoreElements()) - { - ((DTLSReassembler)e.nextElement()).reset(); - } - } - - static class Message - { - private final int message_seq; - private final short msg_type; - private final byte[] body; - - private Message(int message_seq, short msg_type, byte[] body) - { - this.message_seq = message_seq; - this.msg_type = msg_type; - this.body = body; - } - - public int getSeq() - { - return message_seq; - } - - public short getType() - { - return msg_type; - } - - public byte[] getBody() - { - return body; - } - } - - static class RecordLayerBuffer extends ByteArrayOutputStream - { - RecordLayerBuffer(int size) - { - super(size); - } - - void sendToRecordLayer(DTLSRecordLayer recordLayer) throws IOException - { - recordLayer.send(buf, 0, count); - buf = null; - } - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/UDPTransport.java b/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/UDPTransport.java deleted file mode 100644 index f6c96b92..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/crypto/tls/UDPTransport.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.bouncycastle.crypto.tls; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; - -public class UDPTransport - implements DatagramTransport -{ - protected final static int MIN_IP_OVERHEAD = 20; - protected final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64; - protected final static int UDP_OVERHEAD = 8; - - protected final DatagramSocket socket; - protected final int receiveLimit, sendLimit; - - public UDPTransport(DatagramSocket socket, int mtu) - throws IOException - { - // - // In 1.3 and earlier sockets were bound and connected during creation - // - //if (!socket.isBound() || !socket.isConnected()) - //{ - // throw new IllegalArgumentException("'socket' must be bound and connected"); - //} - - this.socket = socket; - - // NOTE: As of JDK 1.6, can use NetworkInterface.getMTU - - this.receiveLimit = mtu - MIN_IP_OVERHEAD - UDP_OVERHEAD; - this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD; - } - - public int getReceiveLimit() - { - return receiveLimit; - } - - public int getSendLimit() - { - // TODO[DTLS] Implement Path-MTU discovery? - return sendLimit; - } - - public int receive(byte[] buf, int off, int len, int waitMillis) - throws IOException - { - socket.setSoTimeout(waitMillis); - - if (off == 0) - { - DatagramPacket packet = new DatagramPacket(buf, len); - socket.receive(packet); - - return packet.getLength(); - } - else - { - byte[] rv = new byte[len]; - - DatagramPacket packet = new DatagramPacket(rv, len); - socket.receive(packet); - - System.arraycopy(rv, 0, buf, off, packet.getLength()); - - return packet.getLength(); - } - } - - public void send(byte[] buf, int off, int len) - throws IOException - { - if (len > getSendLimit()) - { - /* - * RFC 4347 4.1.1. "If the application attempts to send a record larger than the MTU, - * the DTLS implementation SHOULD generate an error, thus avoiding sending a packet - * which will be fragmented." - */ - throw new TlsFatalAlert(AlertDescription.internal_error); - } - - if (off == 0) - { - DatagramPacket packet = new DatagramPacket(buf, len); - socket.send(packet); - } - else - { - byte[] data = new byte[len]; - - System.arraycopy(buf, off, data, 0, len); - - DatagramPacket packet = new DatagramPacket(data, len); - socket.send(packet); - } - } - - public void close() - throws IOException - { - socket.close(); - } -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/i18n/LocalizedMessage.java b/core/src/main/jdk1.1/org/bouncycastle/i18n/LocalizedMessage.java deleted file mode 100644 index c1c4c58a..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/i18n/LocalizedMessage.java +++ /dev/null @@ -1,464 +0,0 @@ -package org.bouncycastle.i18n; - -import org.bouncycastle.i18n.filter.Filter; -import org.bouncycastle.i18n.filter.TrustedInput; -import org.bouncycastle.i18n.filter.UntrustedInput; -import org.bouncycastle.i18n.filter.UntrustedUrlInput; - -import java.io.UnsupportedEncodingException; -import java.text.DateFormat; -import java.text.Format; -import java.text.MessageFormat; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import java.util.TimeZone; - -public class LocalizedMessage -{ - protected static final int NO_FILTER = 0; - protected static final int FILTER = 1; - protected static final int FILTER_URL = 2; - - protected String id; - protected String resource; - - // ISO-8859-1 is the default encoding - public static final String DEFAULT_ENCODING = "ISO-8859-1"; - protected String encoding = DEFAULT_ENCODING; - - protected FilteredArguments arguments; - protected FilteredArguments extraArgs = null; - - protected Filter filter = null; - - protected ClassLoader loader = null; - - /** - * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the - * RessourceBundle and <code>id</code> as the message bundle id the resource file. - * @param resource base name of the resource file - * @param id the id of the corresponding bundle in the resource file - * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code> - */ - public LocalizedMessage(String resource,String id) throws NullPointerException - { - if (resource == null || id == null) - { - throw new NullPointerException(); - } - this.id = id; - this.resource = resource; - arguments = new FilteredArguments(); - } - - /** - * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the - * RessourceBundle and <code>id</code> as the message bundle id the resource file. - * @param resource base name of the resource file - * @param id the id of the corresponding bundle in the resource file - * @param encoding the encoding of the resource file - * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code> - * @throws UnsupportedEncodingException if the encoding is not supported - */ - public LocalizedMessage(String resource,String id, String encoding) throws NullPointerException, UnsupportedEncodingException - { - if (resource == null || id == null) - { - throw new NullPointerException(); - } - this.id = id; - this.resource = resource; - arguments = new FilteredArguments(); - this.encoding = encoding; - } - - /** - * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the - * RessourceBundle and <code>id</code> as the message bundle id the resource file. - * @param resource base name of the resource file - * @param id the id of the corresponding bundle in the resource file - * @param arguments an array containing the arguments for the message - * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code> - */ - public LocalizedMessage(String resource, String id, Object[] arguments) throws NullPointerException - { - if (resource == null || id == null || arguments == null) - { - throw new NullPointerException(); - } - this.id = id; - this.resource = resource; - this.arguments = new FilteredArguments(arguments); - } - - /** - * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the - * RessourceBundle and <code>id</code> as the message bundle id the resource file. - * @param resource base name of the resource file - * @param id the id of the corresponding bundle in the resource file - * @param encoding the encoding of the resource file - * @param arguments an array containing the arguments for the message - * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code> - * @throws UnsupportedEncodingException if the encoding is not supported - */ - public LocalizedMessage(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException - { - if (resource == null || id == null || arguments == null) - { - throw new NullPointerException(); - } - this.id = id; - this.resource = resource; - this.arguments = new FilteredArguments(arguments); - this.encoding = encoding; - } - - /** - * Reads the entry <code>id + "." + key</code> from the resource file and returns a - * formated message for the given Locale and TimeZone. - * @param key second part of the entry id - * @param loc the used {@link Locale} - * @param timezone the used {@link TimeZone} - * @return a Strng containing the localized message - * @throws MissingEntryException if the resource file is not available or the entry does not exist. - */ - public String getEntry(String key,Locale loc, TimeZone timezone) throws MissingEntryException - { - String entry = id; - if (key != null) - { - entry += "." + key; - } - - try - { - ResourceBundle bundle; - if (loader == null) - { - bundle = ResourceBundle.getBundle(resource,loc); - } - else - { - bundle = ResourceBundle.getBundle(resource, loc); - } - String result = bundle.getString(entry); - if (!encoding.equals(DEFAULT_ENCODING)) - { - result = new String(result.getBytes(DEFAULT_ENCODING), encoding); - } - if (!arguments.isEmpty()) - { - result = formatWithTimeZone(result,arguments.getFilteredArgs(loc),loc,timezone); - } - result = addExtraArgs(result, loc); - return result; - } - catch (MissingResourceException mre) - { - throw new MissingEntryException("Can't find entry " + entry + " in resource file " + resource + ".", - resource, - entry, - loc, - loader != null ? loader : this.getClassLoader()); - } - catch (UnsupportedEncodingException use) - { - // should never occur - cause we already test this in the constructor - throw new RuntimeException(use.toString()); - } - } - - protected String formatWithTimeZone( - String template, - Object[] arguments, - Locale locale, - TimeZone timezone) - { - MessageFormat mf = new MessageFormat(" "); - mf.setLocale(locale); - mf.applyPattern(template); - if (!timezone.equals(TimeZone.getDefault())) - { - Format[] formats = mf.getFormats(); - for (int i = 0; i < formats.length; i++) - { - if (formats[i] instanceof DateFormat) - { - DateFormat temp = (DateFormat) formats[i]; - temp.setTimeZone(timezone); - mf.setFormat(i,temp); - } - } - } - return mf.format(arguments); - } - - protected String addExtraArgs(String msg, Locale locale) - { - if (extraArgs != null) - { - StringBuffer sb = new StringBuffer(msg); - Object[] filteredArgs = extraArgs.getFilteredArgs(locale); - for (int i = 0; i < filteredArgs.length; i++) - { - sb.append(filteredArgs[i]); - } - msg = sb.toString(); - } - return msg; - } - - /** - * Sets the {@link Filter} that is used to filter the arguments of this message - * @param filter the {@link Filter} to use. <code>null</code> to disable filtering. - */ - public void setFilter(Filter filter) - { - arguments.setFilter(filter); - if (extraArgs != null) - { - extraArgs.setFilter(filter); - } - this.filter = filter; - } - - /** - * Returns the current filter. - * @return the current filter - */ - public Filter getFilter() - { - return filter; - } - - /** - * Set the {@link ClassLoader} which loads the resource files. If it is set to <code>null</code> - * then the default {@link ClassLoader} is used. - * @param loader the {@link ClassLoader} which loads the resource files - */ - public void setClassLoader(ClassLoader loader) - { - this.loader = loader; - } - - /** - * Returns the {@link ClassLoader} which loads the resource files or <code>null</code> - * if the default ClassLoader is used. - * @return the {@link ClassLoader} which loads the resource files - */ - public ClassLoader getClassLoader() - { - return loader; - } - - /** - * Returns the id of the message in the resource bundle. - * @return the id of the message - */ - public String getId() - { - return id; - } - - /** - * Returns the name of the resource bundle for this message - * @return name of the resource file - */ - public String getResource() - { - return resource; - } - - /** - * Returns an <code>Object[]</code> containing the message arguments. - * @return the message arguments - */ - public Object[] getArguments() - { - return arguments.getArguments(); - } - - /** - * - * @param extraArg - */ - public void setExtraArgument(Object extraArg) - { - setExtraArguments(new Object[] {extraArg}); - } - - /** - * - * @param extraArgs - */ - public void setExtraArguments(Object[] extraArgs) - { - if (extraArgs != null) - { - this.extraArgs = new FilteredArguments(extraArgs); - this.extraArgs.setFilter(filter); - } - else - { - this.extraArgs = null; - } - } - - /** - * - * @return - */ - public Object[] getExtraArgs() - { - return (extraArgs == null) ? null : extraArgs.getArguments(); - } - - protected class FilteredArguments - { - - protected Filter filter = null; - - protected boolean[] isLocaleSpecific; - protected int[] argFilterType; - protected Object[] arguments; - protected Object[] unpackedArgs; - protected Object[] filteredArgs; - - FilteredArguments() - { - this(new Object[0]); - } - - FilteredArguments(Object[] args) - { - this.arguments = args; - this.unpackedArgs = new Object[args.length]; - this.filteredArgs = new Object[args.length]; - this.isLocaleSpecific = new boolean[args.length]; - this.argFilterType = new int[args.length]; - for (int i = 0; i < args.length; i++) - { - if (args[i] instanceof TrustedInput) - { - this.unpackedArgs[i] = ((TrustedInput) args[i]).getInput(); - argFilterType[i] = NO_FILTER; - } - else if (args[i] instanceof UntrustedInput) - { - this.unpackedArgs[i] = ((UntrustedInput) args[i]).getInput(); - if (args[i] instanceof UntrustedUrlInput) - { - argFilterType[i] = FILTER_URL; - } - else - { - argFilterType[i] = FILTER; - } - } - else - { - this.unpackedArgs[i] = args[i]; - argFilterType[i] = FILTER; - } - - // locale specific - this.isLocaleSpecific[i] = (this.unpackedArgs[i] instanceof LocaleString); - } - } - - public boolean isEmpty() - { - return unpackedArgs.length == 0; - } - - public Object[] getArguments() - { - return arguments; - } - - public Object[] getFilteredArgs(Locale locale) - { - Object[] result = new Object[unpackedArgs.length]; - for (int i = 0; i < unpackedArgs.length; i++) - { - Object arg; - if (filteredArgs[i] != null) - { - arg = filteredArgs[i]; - } - else - { - arg = unpackedArgs[i]; - if (isLocaleSpecific[i]) - { - // get locale - arg = ((LocaleString) arg).getLocaleString(locale); - arg = filter(argFilterType[i], arg); - } - else - { - arg = filter(argFilterType[i], arg); - filteredArgs[i] = arg; - } - } - result[i] = arg; - } - return result; - } - - private Object filter(int type, Object obj) - { - if (filter != null) - { - Object o = (null == obj) ? "null" : obj; - switch (type) - { - case NO_FILTER: - return o; - case FILTER: - return filter.doFilter(o.toString()); - case FILTER_URL: - return filter.doFilterUrl(o.toString()); - default: - return null; - } - } - else - { - return obj; - } - } - - public Filter getFilter() - { - return filter; - } - - public void setFilter(Filter filter) - { - if (filter != this.filter) - { - for (int i = 0; i < unpackedArgs.length; i++) - { - filteredArgs[i] = null; - } - } - this.filter = filter; - } - - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - sb.append("Resource: \"").append(resource); - sb.append("\" Id: \"").append(id).append("\""); - sb.append(" Arguments: ").append(arguments.getArguments().length).append(" normal, ") - .append(extraArgs.getArguments().length).append(" extra"); - sb.append(" Encoding: ").append(encoding); - sb.append(" ClassLoader: ").append(loader); - return sb.toString(); - } - -} diff --git a/core/src/main/jdk1.1/org/bouncycastle/i18n/MissingEntryException.java b/core/src/main/jdk1.1/org/bouncycastle/i18n/MissingEntryException.java deleted file mode 100644 index 1400338f..00000000 --- a/core/src/main/jdk1.1/org/bouncycastle/i18n/MissingEntryException.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.bouncycastle.i18n; - -import java.net.URL; -import java.util.Locale; - -public class MissingEntryException extends RuntimeException -{ - - protected final String resource; - protected final String key; - protected final ClassLoader loader; - protected final Locale locale; - - private String debugMsg; - - public MissingEntryException(String message, String resource, String key, Locale locale, ClassLoader loader) - { - super(message); - this.resource = resource; - this.key = key; - this.locale = locale; - this.loader = loader; - } - - public MissingEntryException(String message, Throwable cause, String resource, String key, Locale locale, ClassLoader loader) - { - super(message + ": " + cause); - this.resource = resource; - this.key = key; - this.locale = locale; - this.loader = loader; - } - - public String getKey() - { - return key; - } - - public String getResource() - { - return resource; - } - - public ClassLoader getClassLoader() - { - return loader; - } - - public Locale getLocale() - { - return locale; - } - - public String getDebugMsg() - { - if (debugMsg == null) - { - debugMsg = "Can not find entry " + key + " in resource file " + resource + " for the locale " + locale + "."; - } - return debugMsg; - } - -} |