diff --git a/CONTRIBUTORS.html b/CONTRIBUTORS.html index e915639dfc..e8721a6f88 100644 --- a/CONTRIBUTORS.html +++ b/CONTRIBUTORS.html @@ -564,11 +564,14 @@
  • zhsnew <https://github.com/zhsnew> - correct AsconCXof128 implementation and add test vectors
  • mt-johan <https://github.com/mt-johan> - patch to preserve PRF on initializing from protectionAlgorithm with PBMAC1.
  • oscerd <https://github.com/oscerd> - comment corrections in GMSSRootSig.java.
  • -
  • Léonard Dallot <leonard.dallot@taztag.com> - initial patches for GNU PG Divert to card format support.
  • +
  • Léonard Dallot <leonard.dallot@taztag.com> - initial patches for GNU PG Divert to card format support.
  • Linuka Ratnayake <https://github.com/linukaratnayake> - initial patches for including KEM-type algorithms in TLS key shares.
  • Rune Flobakk <https://github.com/runeflobakk> - initial gradle mods for BOM (Bill of Materials) creation.
  • Jon Marius Venstad <https://github.com/jonmv> - Fixed a KangarooTwelve padding bug caused by premature absorption of queued data.
  • Lomig Mégard <https://github.com/lomigmegard> - BLAKE2 defensive improvements and cleanup.
  • +
  • Prasanth Sundararajan <prasanth.srihari@gmail.com> - identification of the LDAPStoreHelper wildcard bug (see CVE-2023-33201).
  • +
  • XlabAI Team of Tencent Xuanwu Lab, Atuin Automated Vulnerability Discovery Engine, Lili Tang, Guannan Wang, and Guancheng Li<xlabai@tencent.com> - detection of the DSTU4145 random number defect, correction of the G3413BlockCipher class (see CVE-2025-14813).
  • +
  • stevemit <https://github.com/stevemit> - Identified incorrect tagging in the AuthEnvelopedData stream generator.
  • diff --git a/bc-build.properties b/bc-build.properties index c9f533c960..52e1543237 100644 --- a/bc-build.properties +++ b/bc-build.properties @@ -3,9 +3,9 @@ # intended to hold user-specific settings that are *not* committed to # the repository. -release.suffix: 1.83 -release.name: 1.83 -release.version: 1.83 +release.suffix: 1.84-SNAPSHOT +release.name: 1.84-SNAPSHOT +release.version: 1.83.99 release.debug: false mail.jar.home: ./libs/javax.mail-1.4.7.jar diff --git a/core/src/main/j2me/org/bouncycastle/asn1/cms/Time.java b/core/src/main/j2me/org/bouncycastle/asn1/cms/Time.java deleted file mode 100644 index 7819d4ca95..0000000000 --- a/core/src/main/j2me/org/bouncycastle/asn1/cms/Time.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.bouncycastle.asn1.cms; - -import java.util.Calendar; -import java.util.Date; - -import org.bouncycastle.asn1.ASN1Choice; -import org.bouncycastle.asn1.ASN1Object; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.ASN1GeneralizedTime; -import org.bouncycastle.asn1.ASN1UTCTime; - -public class Time - extends ASN1Object - implements ASN1Choice -{ - ASN1Primitive time; - - public static Time getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - if (!explicit) - { - throw new IllegalArgumentException("choice item must be explicitly tagged"); - } - - return getInstance(obj.getExplicitBaseObject()); - } - - public Time( - ASN1Primitive time) - { - if (!(time instanceof ASN1UTCTime) - && !(time instanceof ASN1GeneralizedTime)) - { - throw new IllegalArgumentException("unknown object passed to Time"); - } - - this.time = time; - } - - /** - * creates a time object from a given date - if the date is between 1950 - * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime - * is used. - */ - public Time( - Date date) - { - Calendar calendar = Calendar.getInstance(); - - calendar.setTime(date); - - int year = calendar.get(Calendar.YEAR); - - if (year < 1950 || year > 2049) - { - time = new ASN1GeneralizedTime(date); - } - else - { - time = new ASN1UTCTime(date); - } - } - - public static Time getInstance( - Object obj) - { - if (obj == null || obj instanceof Time) - { - return (Time)obj; - } - else if (obj instanceof ASN1UTCTime) - { - return new Time((ASN1UTCTime)obj); - } - else if (obj instanceof ASN1GeneralizedTime) - { - return new Time((ASN1GeneralizedTime)obj); - } - - throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); - } - - public String getTime() - { - if (time instanceof ASN1UTCTime) - { - return ((ASN1UTCTime)time).getAdjustedTime(); - } - else - { - return ((ASN1GeneralizedTime)time).getTime(); - } - } - - public Date getDate() - { - if (time instanceof ASN1UTCTime) - { - return ((ASN1UTCTime)time).getAdjustedDate(); - } - else - { - return ((ASN1GeneralizedTime)time).getDate(); - } - } - - /** - * Produce an object suitable for an ASN1OutputStream. - *
    -     * Time ::= CHOICE {
    -     *             utcTime        UTCTime,
    -     *             generalTime    GeneralizedTime }
    -     * 
    - */ - public ASN1Primitive toASN1Primitive() - { - return time; - } - - public String toString() - { - return getTime(); - } -} diff --git a/core/src/main/j2me/org/bouncycastle/asn1/eac/PackedDate.java b/core/src/main/j2me/org/bouncycastle/asn1/eac/PackedDate.java deleted file mode 100644 index 2259eb894d..0000000000 --- a/core/src/main/j2me/org/bouncycastle/asn1/eac/PackedDate.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.bouncycastle.asn1.eac; - -import org.bouncycastle.util.Arrays; - -/** - * EAC encoding date object - */ -public class PackedDate -{ - private byte[] time; - - public PackedDate( - String time) - { - this.time = convert(time); - } - - private byte[] convert(String sTime) - { - char[] digs = sTime.toCharArray(); - byte[] date = new byte[6]; - - for (int i = 0; i != 6; i++) - { - date[i] = (byte)(digs[i] - '0'); - } - - return date; - } - - PackedDate( - byte[] bytes) - { - this.time = bytes; - } - - public int hashCode() - { - return Arrays.hashCode(time); - } - - public boolean equals(Object o) - { - if (!(o instanceof PackedDate)) - { - return false; - } - - PackedDate other = (PackedDate)o; - - return Arrays.areEqual(time, other.time); - } - - public String toString() - { - char[] dateC = new char[time.length]; - - for (int i = 0; i != dateC.length; i++) - { - dateC[i] = (char)((time[i] & 0xff) + '0'); - } - - return new String(dateC); - } - - public byte[] getEncoding() - { - return time; - } -} diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1Generator.java b/core/src/main/java/org/bouncycastle/asn1/ASN1Generator.java index a9b9f5ba56..e012e8980f 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1Generator.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1Generator.java @@ -27,4 +27,16 @@ public ASN1Generator(OutputStream out) * @return the stream that is directly encoded to. */ public abstract OutputStream getRawOutputStream(); + + static int inheritConstructedFlag(int intoTag, int fromTag) + { + if ((fromTag & BERTags.CONSTRUCTED) != 0) + { + return intoTag | BERTags.CONSTRUCTED; + } + else + { + return intoTag & ~BERTags.CONSTRUCTED; + } + } } diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1Integer.java b/core/src/main/java/org/bouncycastle/asn1/ASN1Integer.java index 55b48c60c8..3968aa417d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1Integer.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1Integer.java @@ -20,6 +20,15 @@ ASN1Primitive fromImplicitPrimitive(DEROctetString octetString) } }; + private static final ASN1Integer[] SMALL_CONSTANTS = new ASN1Integer[17]; + + public static final ASN1Integer ZERO; + public static final ASN1Integer ONE; + public static final ASN1Integer TWO; + public static final ASN1Integer THREE; + public static final ASN1Integer FOUR; + public static final ASN1Integer FIVE; + static final int SIGN_EXT_SIGNED = 0xFFFFFFFF; static final int SIGN_EXT_UNSIGNED = 0xFF; @@ -76,6 +85,48 @@ public static ASN1Integer getTagged(ASN1TaggedObject taggedObject, boolean decla return (ASN1Integer)TYPE.getTagged(taggedObject, declaredExplicit); } + public static ASN1Integer valueOf(int value) + { + if (value >= 0L && value < SMALL_CONSTANTS.length) + return SMALL_CONSTANTS[value]; + + return new ASN1Integer(value); + } + + public static ASN1Integer valueOf(long value) + { + if (value >= 0L && value < SMALL_CONSTANTS.length) + return SMALL_CONSTANTS[(int)value]; + + return new ASN1Integer(value); + } + + static + { + for (int i = 0; i < SMALL_CONSTANTS.length; ++i) + { + SMALL_CONSTANTS[i] = new ASN1Integer(i); + } + + ZERO = SMALL_CONSTANTS[0]; + ONE = SMALL_CONSTANTS[1]; + TWO = SMALL_CONSTANTS[2]; + THREE = SMALL_CONSTANTS[3]; + FOUR = SMALL_CONSTANTS[4]; + FIVE = SMALL_CONSTANTS[5]; + } + + /** + * Construct an INTEGER from the passed in int value. + * + * @param value the int representing the value desired. + */ + public ASN1Integer(int value) + { + this.bytes = BigInteger.valueOf(value).toByteArray(); + this.start = 0; + } + /** * Construct an INTEGER from the passed in long value. * diff --git a/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java b/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java index e7151debab..3e2e4626a8 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java +++ b/core/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java @@ -19,6 +19,36 @@ public abstract class ASN1TaggedObject private static final int PARSED_EXPLICIT = 3; private static final int PARSED_IMPLICIT = 4; + public static ASN1TaggedObject getContextInstance(Object obj) + { + return ASN1Util.checkContextTagClass(checkInstance(obj)); + } + + public static ASN1TaggedObject getContextInstance(Object obj, int tagNo) + { + return ASN1Util.checkContextTag(checkInstance(obj), tagNo); + } + + public static ASN1TaggedObject getContextOptional(ASN1Encodable element) + { + ASN1TaggedObject taggedObject = getOptional(element); + if (taggedObject != null && taggedObject.hasContextTag()) + { + return taggedObject; + } + return null; + } + + public static ASN1TaggedObject getContextOptional(ASN1Encodable element, int tagNo) + { + ASN1TaggedObject taggedObject = getOptional(element); + if (taggedObject != null && taggedObject.hasContextTag(tagNo)) + { + return taggedObject; + } + return null; + } + public static ASN1TaggedObject getInstance(Object obj) { if (obj == null || obj instanceof ASN1TaggedObject) diff --git a/core/src/main/java/org/bouncycastle/asn1/BERGenerator.java b/core/src/main/java/org/bouncycastle/asn1/BERGenerator.java index ad2b37ff01..74a59a7b7e 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BERGenerator.java +++ b/core/src/main/java/org/bouncycastle/asn1/BERGenerator.java @@ -41,31 +41,28 @@ private void writeHdr(int tag) throws IOException protected void writeBERHeader(int tag) throws IOException { - if (_tagged) + if (!_tagged) { - int tagNum = _tagNo | BERTags.CONTEXT_SPECIFIC; - - if (_isExplicit) - { - writeHdr(tagNum | BERTags.CONSTRUCTED); - writeHdr(tag); - } - else - { - if ((tag & BERTags.CONSTRUCTED) != 0) - { - writeHdr(tagNum | BERTags.CONSTRUCTED); - } - else - { - writeHdr(tagNum); - } - } + writeHdr(tag); } - else + else if (_isExplicit) { + /* + * X.690-0207 8.14.2. If implicit tagging [..] was not used [..], the encoding shall be constructed + * and the contents octets shall be the complete base encoding. + */ + writeHdr(_tagNo | BERTags.CONTEXT_SPECIFIC | BERTags.CONSTRUCTED); writeHdr(tag); } + else + { + /* + * X.690-0207 8.14.3. If implicit tagging was used [..], then: a) the encoding shall be constructed + * if the base encoding is constructed, and shall be primitive otherwise; and b) the contents octets + * shall be [..] the contents octets of the base encoding. + */ + writeHdr(inheritConstructedFlag(_tagNo | BERTags.CONTEXT_SPECIFIC, tag)); + } } protected void writeBEREnd() throws IOException diff --git a/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java b/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java index dbc8e4b8b9..8132cc7c94 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java +++ b/core/src/main/java/org/bouncycastle/asn1/BEROctetString.java @@ -2,6 +2,8 @@ import java.io.IOException; +import org.bouncycastle.util.Arrays; + /** * ASN.1 OctetStrings, with indefinite length rules, and constructed form support. *

    @@ -19,10 +21,37 @@ public class BEROctetString extends ASN1OctetString { - private static final int DEFAULT_SEGMENT_LIMIT = 1000; + public static final BEROctetString EMPTY = new BEROctetString(EMPTY_OCTETS); - private final int segmentLimit; - private final ASN1OctetString[] elements; + public static BEROctetString fromContents(byte[] contents) + { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + + return internalFromContents(contents); + } + + public static BEROctetString fromContentsOptional(byte[] contents) + { + return contents == null ? null : internalFromContents(contents); + } + + public static BEROctetString withContents(byte[] contents) + { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + + return internalWithContents(contents); + } + + public static BEROctetString withContentsOptional(byte[] contents) + { + return contents == null ? null : internalWithContents(contents); + } /** * Convert a vector of octet strings into a single byte string @@ -58,6 +87,21 @@ static byte[] flattenOctetStrings(ASN1OctetString[] octetStrings) } } + static BEROctetString internalFromContents(byte[] contents) + { + return contents.length < 1 ? EMPTY : new BEROctetString(Arrays.clone(contents)); + } + + static BEROctetString internalWithContents(byte[] contents) + { + return contents.length < 1 ? EMPTY : new BEROctetString(contents); + } + + private static final int DEFAULT_SEGMENT_LIMIT = 1000; + + private final int segmentLimit; + private final ASN1OctetString[] elements; + /** * Create an OCTET-STRING object from a byte[] * @param string the octets making up the octet string. diff --git a/core/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java b/core/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java index 8be481fc9f..29b4e9edc2 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java +++ b/core/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java @@ -71,14 +71,14 @@ private class BufferedBEROctetStream { private byte[] _buf; private int _off; - private DEROutputStream _derOut; + private ASN1OutputStream _asn1Out; BufferedBEROctetStream( byte[] buf) { _buf = buf; _off = 0; - _derOut = new DEROutputStream(_out); + _asn1Out = ASN1OutputStream.create(_out); } public void write( @@ -89,7 +89,7 @@ public void write( if (_off == _buf.length) { - DEROctetString.encode(_derOut, true, _buf, 0, _buf.length); + DEROctetString.encode(_asn1Out, true, _buf, 0, _buf.length); _off = 0; } } @@ -110,13 +110,13 @@ public void write(byte[] b, int off, int len) throws IOException { System.arraycopy(b, off, _buf, _off, available); count += available; - DEROctetString.encode(_derOut, true, _buf, 0, bufLen); + DEROctetString.encode(_asn1Out, true, _buf, 0, bufLen); } int remaining; while ((remaining = (len - count)) >= bufLen) { - DEROctetString.encode(_derOut, true, b, off + count, bufLen); + DEROctetString.encode(_asn1Out, true, b, off + count, bufLen); count += bufLen; } @@ -129,10 +129,10 @@ public void close() { if (_off != 0) { - DEROctetString.encode(_derOut, true, _buf, 0, _off); + DEROctetString.encode(_asn1Out, true, _buf, 0, _off); } - _derOut.flushInternal(); + _asn1Out.flushInternal(); writeBEREnd(); } diff --git a/core/src/main/java/org/bouncycastle/asn1/BEROutputStream.java b/core/src/main/java/org/bouncycastle/asn1/BEROutputStream.java deleted file mode 100644 index 6bced5e4dd..0000000000 --- a/core/src/main/java/org/bouncycastle/asn1/BEROutputStream.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.bouncycastle.asn1; - -import java.io.OutputStream; - -/** - * A class which writes indefinite and definite length objects. Objects which specify DER will be - * encoded accordingly, but DL or BER objects will be encoded as defined. - */ -class BEROutputStream - extends ASN1OutputStream -{ - /** - * Base constructor. - * - * @param os - * target output stream. - */ - BEROutputStream(OutputStream os) - { - super(os); - } -} diff --git a/core/src/main/java/org/bouncycastle/asn1/BERSequence.java b/core/src/main/java/org/bouncycastle/asn1/BERSequence.java index 93d9783eb0..2c52cd559f 100644 --- a/core/src/main/java/org/bouncycastle/asn1/BERSequence.java +++ b/core/src/main/java/org/bouncycastle/asn1/BERSequence.java @@ -13,6 +13,18 @@ public class BERSequence extends ASN1Sequence { + public static final BERSequence EMPTY = new BERSequence(); + + public static BERSequence fromElementsOptional(ASN1Encodable[] elements) + { + if (elements == null) + { + return null; + } + + return elements.length < 1 ? EMPTY : new BERSequence(elements); + } + /** * Create an empty sequence. */ diff --git a/core/src/main/java/org/bouncycastle/asn1/DERGenerator.java b/core/src/main/java/org/bouncycastle/asn1/DERGenerator.java index ecd00e5618..58e5cd10a3 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERGenerator.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERGenerator.java @@ -83,35 +83,28 @@ void writeDEREncoded( byte[] bytes) throws IOException { - if (_tagged) + if (!_tagged) { - int tagNum = _tagNo | BERTags.CONTEXT_SPECIFIC; - - if (_isExplicit) - { - int newTag = _tagNo | BERTags.CONSTRUCTED | BERTags.CONTEXT_SPECIFIC; - - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - writeDEREncoded(bOut, tag, bytes); - - writeDEREncoded(_out, newTag, bOut.toByteArray()); - } - else - { - if ((tag & BERTags.CONSTRUCTED) != 0) - { - writeDEREncoded(_out, tagNum | BERTags.CONSTRUCTED, bytes); - } - else - { - writeDEREncoded(_out, tagNum, bytes); - } - } + writeDEREncoded(_out, tag, bytes); + } + else if (_isExplicit) + { + /* + * X.690-0207 8.14.2. If implicit tagging [..] was not used [..], the encoding shall be constructed + * and the contents octets shall be the complete base encoding. + */ + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + writeDEREncoded(bOut, tag, bytes); + writeDEREncoded(_out, _tagNo | BERTags.CONTEXT_SPECIFIC | BERTags.CONSTRUCTED, bOut.toByteArray()); } else { - writeDEREncoded(_out, tag, bytes); + /* + * X.690-0207 8.14.3. If implicit tagging was used [..], then: a) the encoding shall be constructed + * if the base encoding is constructed, and shall be primitive otherwise; and b) the contents octets + * shall be [..] the contents octets of the base encoding. + */ + writeDEREncoded(_out, inheritConstructedFlag(_tagNo | BERTags.CONTEXT_SPECIFIC, tag), bytes); } } } diff --git a/core/src/main/java/org/bouncycastle/asn1/DEROctetString.java b/core/src/main/java/org/bouncycastle/asn1/DEROctetString.java index 6d11821ae0..9acac9f450 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DEROctetString.java +++ b/core/src/main/java/org/bouncycastle/asn1/DEROctetString.java @@ -2,12 +2,56 @@ import java.io.IOException; +import org.bouncycastle.util.Arrays; + /** * Carrier class for a DER encoding OCTET STRING */ public class DEROctetString extends ASN1OctetString { + public static final DEROctetString EMPTY = new DEROctetString(EMPTY_OCTETS); + + public static DEROctetString fromContents(byte[] contents) + { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + + return internalFromContents(contents); + } + + public static DEROctetString fromContentsOptional(byte[] contents) + { + return contents == null ? null : internalFromContents(contents); + } + + public static DEROctetString withContents(byte[] contents) + { + if (contents == null) + { + throw new NullPointerException("'contents' cannot be null"); + } + + return internalWithContents(contents); + } + + public static DEROctetString withContentsOptional(byte[] contents) + { + return contents == null ? null : internalWithContents(contents); + } + + static DEROctetString internalFromContents(byte[] contents) + { + return contents.length < 1 ? EMPTY : new DEROctetString(Arrays.clone(contents)); + } + + static DEROctetString internalWithContents(byte[] contents) + { + return contents.length < 1 ? EMPTY : new DEROctetString(contents); + } + /** * Base constructor. * diff --git a/core/src/main/java/org/bouncycastle/asn1/DERSequence.java b/core/src/main/java/org/bouncycastle/asn1/DERSequence.java index 515aff7246..607ff289d0 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DERSequence.java +++ b/core/src/main/java/org/bouncycastle/asn1/DERSequence.java @@ -11,11 +11,23 @@ public class DERSequence extends ASN1Sequence { + public static final DERSequence EMPTY = new DERSequence(); + public static DERSequence convert(ASN1Sequence seq) { return (DERSequence)seq.toDERObject(); } + public static DERSequence fromElementsOptional(ASN1Encodable[] elements) + { + if (elements == null) + { + return null; + } + + return elements.length < 1 ? EMPTY : new DERSequence(elements); + } + private int contentsLength = -1; /** diff --git a/core/src/main/java/org/bouncycastle/asn1/DLSequence.java b/core/src/main/java/org/bouncycastle/asn1/DLSequence.java index d510567733..56d525b9ad 100644 --- a/core/src/main/java/org/bouncycastle/asn1/DLSequence.java +++ b/core/src/main/java/org/bouncycastle/asn1/DLSequence.java @@ -8,6 +8,23 @@ public class DLSequence extends ASN1Sequence { + public static final DLSequence EMPTY = new DLSequence(); + + public static DLSequence convert(ASN1Sequence seq) + { + return (DLSequence)seq.toDLObject(); + } + + public static DLSequence fromElementsOptional(ASN1Encodable[] elements) + { + if (elements == null) + { + return null; + } + + return elements.length < 1 ? EMPTY : new DLSequence(elements); + } + private int contentsLength = -1; /** diff --git a/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java index ea543835f4..a472a992f9 100644 --- a/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java @@ -733,4 +733,12 @@ public interface BCObjectIdentifiers ASN1ObjectIdentifier snova_75_33_2_esk = snova.branch("42"); ASN1ObjectIdentifier snova_75_33_2_shake_ssk = snova.branch("43"); ASN1ObjectIdentifier snova_75_33_2_shake_esk = snova.branch("44"); + + /** + * NTRU+ + * */ + ASN1ObjectIdentifier ntruPlus = bc_sig.branch("15"); + ASN1ObjectIdentifier ntruPlus768 = ntruPlus.branch("1"); + ASN1ObjectIdentifier ntruPlus864 = ntruPlus.branch("2"); + ASN1ObjectIdentifier ntruPlus1152 = ntruPlus.branch("3"); } diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410ParamSetParameters.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410ParamSetParameters.java index d084fa6957..ef750f532d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410ParamSetParameters.java +++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/ECGOST3410ParamSetParameters.java @@ -51,7 +51,7 @@ public ECGOST3410ParamSetParameters( this.b = new ASN1Integer(b); this.p = new ASN1Integer(p); this.q = new ASN1Integer(q); - this.x = new ASN1Integer(x); + this.x = ASN1Integer.valueOf(x); this.y = new ASN1Integer(y); } diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410NamedParameters.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410NamedParameters.java index 6c398b5df4..5ef811c6af 100644 --- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410NamedParameters.java +++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410NamedParameters.java @@ -15,7 +15,7 @@ public class GOST3410NamedParameters static final Hashtable params = new Hashtable(); static final Hashtable names = new Hashtable(); - static private GOST3410ParamSetParameters cryptoProA = new GOST3410ParamSetParameters( + private static final GOST3410ParamSetParameters cryptoProA = new GOST3410ParamSetParameters( 1024, new BigInteger("127021248288932417465907042777176443525787653508916535812817507265705031260985098497423188333483401180925999995120988934130659205614996724254121049274349357074920312769561451689224110579311248812610229678534638401693520013288995000362260684222750813532307004517341633685004541062586971416883686778842537820383"), new BigInteger("68363196144955700784444165611827252895102170888761442055095051287550314083023"), @@ -32,7 +32,7 @@ public class GOST3410NamedParameters ); - static private GOST3410ParamSetParameters cryptoProB = new GOST3410ParamSetParameters( + private static final GOST3410ParamSetParameters cryptoProB = new GOST3410ParamSetParameters( 1024, new BigInteger("139454871199115825601409655107690713107041707059928031797758001454375765357722984094124368522288239833039114681648076688236921220737322672160740747771700911134550432053804647694904686120113087816240740184800477047157336662926249423571248823968542221753660143391485680840520336859458494803187341288580489525163"), new BigInteger("79885141663410976897627118935756323747307951916507639758300472692338873533959"), @@ -53,7 +53,7 @@ public class GOST3410NamedParameters //} ); - static private GOST3410ParamSetParameters cryptoProXchA = new GOST3410ParamSetParameters( + private static final GOST3410ParamSetParameters cryptoProXchA = new GOST3410ParamSetParameters( 1024, new BigInteger("142011741597563481196368286022318089743276138395243738762872573441927459393512718973631166078467600360848946623567625795282774719212241929071046134208380636394084512691828894000571524625445295769349356752728956831541775441763139384457191755096847107846595662547942312293338483924514339614727760681880609734239"), new BigInteger("91771529896554605945588149018382750217296858393520724172743325725474374979801"), diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410ParamSetParameters.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410ParamSetParameters.java index 58089e00dc..d915ce138a 100644 --- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410ParamSetParameters.java +++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410ParamSetParameters.java @@ -95,7 +95,7 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(4); - v.add(new ASN1Integer(keySize)); + v.add(ASN1Integer.valueOf(keySize)); v.add(p); v.add(q); v.add(a); diff --git a/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java b/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java index 129034b649..15cbc572d0 100644 --- a/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java +++ b/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE128_params.java @@ -101,7 +101,7 @@ public ASN1Primitive toASN1Primitive() if (outputLength != DEF_LENGTH) { - v.add(new ASN1Integer(outputLength)); + v.add(ASN1Integer.valueOf(outputLength)); } if (customizationString.length != 0) diff --git a/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java b/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java index 390c9039ac..76963fa35b 100644 --- a/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java +++ b/core/src/main/java/org/bouncycastle/asn1/nist/KMACwithSHAKE256_params.java @@ -101,7 +101,7 @@ public ASN1Primitive toASN1Primitive() if (outputLength != DEF_LENGTH) { - v.add(new ASN1Integer(outputLength)); + v.add(ASN1Integer.valueOf(outputLength)); } if (customizationString.length != 0) diff --git a/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java b/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java index 9de94728eb..2a05b4c688 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java +++ b/core/src/main/java/org/bouncycastle/asn1/ocsp/ResponseData.java @@ -26,8 +26,8 @@ public class ResponseData extends ASN1Object { - private static final ASN1Integer V1 = new ASN1Integer(0); - + private static final ASN1Integer V1 = ASN1Integer.ZERO; + private boolean versionPresent; private ASN1Integer version; diff --git a/core/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java b/core/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java index 28c64290c7..7b5f8cce07 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java +++ b/core/src/main/java/org/bouncycastle/asn1/ocsp/TBSRequest.java @@ -15,7 +15,7 @@ public class TBSRequest extends ASN1Object { - private static final ASN1Integer V1 = new ASN1Integer(0); + private static final ASN1Integer V1 = ASN1Integer.ZERO; ASN1Integer version; GeneralName requestorName; diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java index b092bb8d15..b60e44f9bb 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java @@ -36,7 +36,7 @@ public class CertificationRequestInfo extends ASN1Object { - ASN1Integer version = new ASN1Integer(0); + ASN1Integer version = ASN1Integer.ZERO; X500Name subject; SubjectPublicKeyInfo subjectPKInfo; ASN1Set attributes = null; diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java index aeb8f01e6e..bd56af938f 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/DHParameter.java @@ -25,7 +25,7 @@ public DHParameter( if (l != 0) { - this.l = new ASN1Integer(l); + this.l = ASN1Integer.valueOf(l); } else { diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java index d1901fd3c0..5cc30a54fc 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/EncryptedData.java @@ -102,6 +102,6 @@ public ASN1OctetString getContent() public ASN1Primitive toASN1Primitive() { - return new BERSequence(new ASN1Integer(0), data); + return new BERSequence(ASN1Integer.ZERO, data); } } diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java index 055f827b4d..6553430109 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBEParameter.java @@ -25,7 +25,7 @@ public PBEParameter( throw new IllegalArgumentException("salt length must be 8"); } this.salt = new DEROctetString(salt); - this.iterations = new ASN1Integer(iterations); + this.iterations = ASN1Integer.valueOf(iterations); } private PBEParameter( diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java index a59d16c653..882e046c4d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java @@ -102,11 +102,11 @@ public PBKDF2Params( AlgorithmIdentifier prf) { this.octStr = new DEROctetString(Arrays.clone(salt)); - this.iterationCount = new ASN1Integer(iterationCount); + this.iterationCount = ASN1Integer.valueOf(iterationCount); if (keyLength > 0) { - this.keyLength = new ASN1Integer(keyLength); + this.keyLength = ASN1Integer.valueOf(keyLength); } else { diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java index 2d9c94a2f7..b3fab3fded 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java @@ -21,7 +21,7 @@ public PKCS12PBEParams( int iterations) { this.iv = new DEROctetString(salt); - this.iterations = new ASN1Integer(iterations); + this.iterations = ASN1Integer.valueOf(iterations); } private PKCS12PBEParams( diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java index 8d51197178..809d7f1636 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/Pfx.java @@ -72,7 +72,7 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(3); - v.add(new ASN1Integer(3)); + v.add(ASN1Integer.THREE); v.add(contentInfo); if (macData != null) diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java index 61bc110f1a..7f5875519e 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RC2CBCParameter.java @@ -43,7 +43,7 @@ public RC2CBCParameter( int parameterVersion, byte[] iv) { - this.version = new ASN1Integer(parameterVersion); + this.version = ASN1Integer.valueOf(parameterVersion); this.iv = new DEROctetString(iv); } diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java index 8e654cc0f2..4bd2bf9311 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java @@ -170,7 +170,7 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(10); - v.add(new ASN1Integer(version)); // version + v.add(ASN1Integer.valueOf(version)); // version v.add(new ASN1Integer(getModulus())); v.add(new ASN1Integer(getPublicExponent())); v.add(new ASN1Integer(getPrivateExponent())); diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java index 713f83720e..d711216d54 100644 --- a/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java +++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java @@ -24,9 +24,9 @@ public class RSASSAPSSparams public final static AlgorithmIdentifier DEFAULT_HASH_ALGORITHM = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); public final static AlgorithmIdentifier DEFAULT_MASK_GEN_FUNCTION = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, DEFAULT_HASH_ALGORITHM); - public final static ASN1Integer DEFAULT_SALT_LENGTH = new ASN1Integer(20); - public final static ASN1Integer DEFAULT_TRAILER_FIELD = new ASN1Integer(1); - + public final static ASN1Integer DEFAULT_SALT_LENGTH = ASN1Integer.valueOf(20); + public final static ASN1Integer DEFAULT_TRAILER_FIELD = ASN1Integer.ONE; + public static RSASSAPSSparams getInstance( Object obj) { diff --git a/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java b/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java index 890fba67bb..7ac98a19b4 100644 --- a/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKey.java @@ -1,7 +1,6 @@ package org.bouncycastle.asn1.sec; import java.math.BigInteger; -import java.util.Enumeration; import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1Encodable; @@ -24,16 +23,7 @@ public class ECPrivateKey extends ASN1Object { - private ASN1Sequence seq; - - private ECPrivateKey( - ASN1Sequence seq) - { - this.seq = seq; - } - - public static ECPrivateKey getInstance( - Object obj) + public static ECPrivateKey getInstance(Object obj) { if (obj instanceof ECPrivateKey) { @@ -48,70 +38,48 @@ public static ECPrivateKey getInstance( return null; } - /** - * @deprecated use constructor which takes orderBitLength to guarantee correct encoding. - */ - public ECPrivateKey( - BigInteger key) + public static ECPrivateKey getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - this(key.bitLength(), key); + return new ECPrivateKey(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); } - /** - * Base constructor. - * - * @param orderBitLength the bitLength of the order of the curve. - * @param key the private key value. - */ - public ECPrivateKey( - int orderBitLength, - BigInteger key) + public static ECPrivateKey getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key); - - seq = new DERSequence(new ASN1Integer(1), new DEROctetString(bytes)); + return new ECPrivateKey(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); } - /** - * @deprecated use constructor which takes orderBitLength to guarantee correct encoding. - */ - public ECPrivateKey( - BigInteger key, - ASN1Encodable parameters) + private final ASN1Sequence seq; + + private ECPrivateKey(ASN1Sequence seq) { - this(key, null, parameters); + this.seq = seq; } /** - * @deprecated use constructor which takes orderBitLength to guarantee correct encoding. + * Base constructor. + * + * @param orderBitLength the bitLength of the order of the curve. + * @param key the private key value. */ - public ECPrivateKey( - BigInteger key, - ASN1BitString publicKey, - ASN1Encodable parameters) + public ECPrivateKey(int orderBitLength, BigInteger key) { - this(key.bitLength(), key, publicKey, parameters); + byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key); + + seq = new DERSequence(ASN1Integer.ONE, new DEROctetString(bytes)); } - public ECPrivateKey( - int orderBitLength, - BigInteger key, - ASN1Encodable parameters) + public ECPrivateKey(int orderBitLength, BigInteger key, ASN1Encodable parameters) { this(orderBitLength, key, null, parameters); } - public ECPrivateKey( - int orderBitLength, - BigInteger key, - ASN1BitString publicKey, - ASN1Encodable parameters) + public ECPrivateKey(int orderBitLength, BigInteger key, ASN1BitString publicKey, ASN1Encodable parameters) { byte[] bytes = BigIntegers.asUnsignedByteArray((orderBitLength + 7) / 8, key); ASN1EncodableVector v = new ASN1EncodableVector(4); - v.add(new ASN1Integer(1)); + v.add(ASN1Integer.ONE); v.add(new DEROctetString(bytes)); if (parameters != null) @@ -127,25 +95,39 @@ public ECPrivateKey( seq = new DERSequence(v); } - public BigInteger getKey() + public ECPrivateKey(ASN1OctetString privateKey, ASN1Encodable parameters, ASN1BitString publicKey) { - ASN1OctetString octs = (ASN1OctetString)seq.getObjectAt(1); + ASN1EncodableVector v = new ASN1EncodableVector(4); + + v.add(ASN1Integer.ONE); + v.add(privateKey); + + if (parameters != null) + { + v.add(new DERTaggedObject(true, 0, parameters)); + } + + if (publicKey != null) + { + v.add(new DERTaggedObject(true, 1, publicKey)); + } + + seq = new DERSequence(v); + } - return new BigInteger(1, octs.getOctets()); + public BigInteger getKey() + { + return new BigInteger(1, getPrivateKey().getOctets()); } - - public ASN1BitString getPublicKey() + + public ASN1OctetString getPrivateKey() { - return (ASN1BitString)getObjectInTag(1, BERTags.BIT_STRING); + return (ASN1OctetString)seq.getObjectAt(1); } - /** - * @deprecated Use {@link #getParametersObject()} instead and getInstance - * methods or similar to get the object at the desired type. - */ - public ASN1Primitive getParameters() + public ASN1BitString getPublicKey() { - return getParametersObject().toASN1Primitive(); + return (ASN1BitString)getObjectInTag(1, BERTags.BIT_STRING); } public ASN1Object getParametersObject() @@ -155,21 +137,15 @@ public ASN1Object getParametersObject() private ASN1Object getObjectInTag(int tagNo, int baseTagNo) { - Enumeration e = seq.getObjects(); - - while (e.hasMoreElements()) + for (int i = 0, count = seq.size(); i < count; ++i) { - ASN1Encodable obj = (ASN1Encodable)e.nextElement(); - - if (obj instanceof ASN1TaggedObject) + ASN1Encodable element = seq.getObjectAt(i); + ASN1TaggedObject taggedObject = ASN1TaggedObject.getContextOptional(element, tagNo); + if (taggedObject != null) { - ASN1TaggedObject tag = (ASN1TaggedObject)obj; - if (tag.hasContextTag(tagNo)) - { - return baseTagNo < 0 - ? tag.getExplicitBaseObject().toASN1Primitive() - : tag.getBaseUniversal(true, baseTagNo); - } + return baseTagNo < 0 + ? taggedObject.getExplicitBaseObject().toASN1Primitive() + : taggedObject.getBaseUniversal(true, baseTagNo); } } return null; diff --git a/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java index 5ed882ef84..fbe7dbd9e7 100644 --- a/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java +++ b/core/src/main/java/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java @@ -37,7 +37,7 @@ public ECPrivateKeyStructure( { byte[] bytes = BigIntegers.asUnsignedByteArray(key); - seq = new DERSequence(new ASN1Integer(1), new DEROctetString(bytes)); + seq = new DERSequence(ASN1Integer.ONE, new DEROctetString(bytes)); } public ECPrivateKeyStructure( @@ -56,7 +56,7 @@ public ECPrivateKeyStructure( ASN1EncodableVector v = new ASN1EncodableVector(4); - v.add(new ASN1Integer(1)); + v.add(ASN1Integer.ONE); v.add(new DEROctetString(bytes)); if (parameters != null) diff --git a/core/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java index bb215bee6e..023c7b80c5 100644 --- a/core/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java @@ -15,8 +15,9 @@ */ public interface SECObjectIdentifiers { - /** Base OID: 1.3.132.0 */ - static final ASN1ObjectIdentifier ellipticCurve = new ASN1ObjectIdentifier("1.3.132.0"); + static final ASN1ObjectIdentifier certicom = new ASN1ObjectIdentifier("1.3.132"); + + static final ASN1ObjectIdentifier ellipticCurve = certicom.branch("0"); /** sect163k1 OID: 1.3.132.0.1 */ static final ASN1ObjectIdentifier sect163k1 = ellipticCurve.branch("1"); @@ -86,25 +87,52 @@ public interface SECObjectIdentifiers /** secp256r1 OID: 1.3.132.0.prime256v1 */ static final ASN1ObjectIdentifier secp256r1 = X9ObjectIdentifiers.prime256v1; - static final ASN1ObjectIdentifier secg_scheme = new ASN1ObjectIdentifier("1.3.132.1"); + static final ASN1ObjectIdentifier secg_scheme = certicom.branch("1"); + + static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_recommendedKDF = secg_scheme.branch("1"); + static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_specifiedKDF = secg_scheme.branch("2"); + static final ASN1ObjectIdentifier mqvSinglePass_recommendedKDF = secg_scheme.branch("3"); + static final ASN1ObjectIdentifier mqvSinglePass_specifiedKDF = secg_scheme.branch("4"); + static final ASN1ObjectIdentifier mqvFull_recommendedKDF = secg_scheme.branch("5"); + static final ASN1ObjectIdentifier mqvFull_specifiedKDF = secg_scheme.branch("6"); + static final ASN1ObjectIdentifier ecies_recommendedParameters = secg_scheme.branch("7"); + static final ASN1ObjectIdentifier ecies_specifiedParameters = secg_scheme.branch("8"); + + static final ASN1ObjectIdentifier dhSinglePass_stdDH_kdf_schemes = secg_scheme.branch("11"); + + static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha224kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("0"); + static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha256kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("1"); + static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha384kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("2"); + static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha512kdf_scheme = dhSinglePass_stdDH_kdf_schemes.branch("3"); + + static final ASN1ObjectIdentifier ecdh = secg_scheme.branch("12"); + static final ASN1ObjectIdentifier ecmqv = secg_scheme.branch("13"); + + static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_kdf_schemes = secg_scheme.branch("14"); + + static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha224kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("0"); + static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha256kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("1"); + static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha384kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("2"); + static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha512kdf_scheme = dhSinglePass_cofactorDH_kdf_schemes.branch("3"); + + static final ASN1ObjectIdentifier mqvSinglePass_kdf_schemes = secg_scheme.branch("15"); + + static final ASN1ObjectIdentifier mqvSinglePass_sha224kdf_scheme = mqvSinglePass_kdf_schemes.branch("0"); + static final ASN1ObjectIdentifier mqvSinglePass_sha256kdf_scheme = mqvSinglePass_kdf_schemes.branch("1"); + static final ASN1ObjectIdentifier mqvSinglePass_sha384kdf_scheme = mqvSinglePass_kdf_schemes.branch("2"); + static final ASN1ObjectIdentifier mqvSinglePass_sha512kdf_scheme = mqvSinglePass_kdf_schemes.branch("3"); - static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha224kdf_scheme = secg_scheme.branch("11.0"); - static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha256kdf_scheme = secg_scheme.branch("11.1"); - static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha384kdf_scheme = secg_scheme.branch("11.2"); - static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha512kdf_scheme = secg_scheme.branch("11.3"); + static final ASN1ObjectIdentifier mqvFull_kdf_schemes = secg_scheme.branch("16"); - static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha224kdf_scheme = secg_scheme.branch("14.0"); - static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha256kdf_scheme = secg_scheme.branch("14.1"); - static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha384kdf_scheme = secg_scheme.branch("14.2"); - static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha512kdf_scheme = secg_scheme.branch("14.3"); + static final ASN1ObjectIdentifier mqvFull_sha224kdf_scheme = mqvFull_kdf_schemes.branch("0"); + static final ASN1ObjectIdentifier mqvFull_sha256kdf_scheme = mqvFull_kdf_schemes.branch("1"); + static final ASN1ObjectIdentifier mqvFull_sha384kdf_scheme = mqvFull_kdf_schemes.branch("2"); + static final ASN1ObjectIdentifier mqvFull_sha512kdf_scheme = mqvFull_kdf_schemes.branch("3"); - static final ASN1ObjectIdentifier mqvSinglePass_sha224kdf_scheme = secg_scheme.branch("15.0"); - static final ASN1ObjectIdentifier mqvSinglePass_sha256kdf_scheme = secg_scheme.branch("15.1"); - static final ASN1ObjectIdentifier mqvSinglePass_sha384kdf_scheme = secg_scheme.branch("15.2"); - static final ASN1ObjectIdentifier mqvSinglePass_sha512kdf_scheme = secg_scheme.branch("15.3"); + static final ASN1ObjectIdentifier kdf_algorithms = secg_scheme.branch("17"); - static final ASN1ObjectIdentifier mqvFull_sha224kdf_scheme = secg_scheme.branch("16.0"); - static final ASN1ObjectIdentifier mqvFull_sha256kdf_scheme = secg_scheme.branch("16.1"); - static final ASN1ObjectIdentifier mqvFull_sha384kdf_scheme = secg_scheme.branch("16.2"); - static final ASN1ObjectIdentifier mqvFull_sha512kdf_scheme = secg_scheme.branch("16.3"); + static final ASN1ObjectIdentifier x9_63_kdf = kdf_algorithms.branch("0"); + static final ASN1ObjectIdentifier nist_concatenation_kdf = kdf_algorithms.branch("1"); + static final ASN1ObjectIdentifier tls_kdf = kdf_algorithms.branch("2"); + static final ASN1ObjectIdentifier ikev2_kdf = kdf_algorithms.branch("3"); } diff --git a/core/src/main/java/org/bouncycastle/asn1/ua/DSTU4145BinaryField.java b/core/src/main/java/org/bouncycastle/asn1/ua/DSTU4145BinaryField.java index 825ea960d3..cb98e8921e 100644 --- a/core/src/main/java/org/bouncycastle/asn1/ua/DSTU4145BinaryField.java +++ b/core/src/main/java/org/bouncycastle/asn1/ua/DSTU4145BinaryField.java @@ -96,17 +96,17 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(2); - v.add(new ASN1Integer(m)); + v.add(ASN1Integer.valueOf(m)); if (j == 0) //Trinomial { - v.add(new ASN1Integer(k)); + v.add(ASN1Integer.valueOf(k)); } else { ASN1EncodableVector coefs = new ASN1EncodableVector(3); - coefs.add(new ASN1Integer(k)); - coefs.add(new ASN1Integer(j)); - coefs.add(new ASN1Integer(l)); + coefs.add(ASN1Integer.valueOf(k)); + coefs.add(ASN1Integer.valueOf(j)); + coefs.add(ASN1Integer.valueOf(l)); v.add(new DERSequence(coefs)); } diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java b/core/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java index d019aaac75..29949b79bb 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java @@ -11,7 +11,7 @@ */ public class X500NameBuilder { - private X500NameStyle template; + private X500NameStyle style; private Vector rdns = new Vector(); /** @@ -25,13 +25,18 @@ public X500NameBuilder() /** * Constructor using a specified style. * - * @param template the style template for string to DN conversion. + * @param style the X500NameStyle for string to DN conversion. */ - public X500NameBuilder(X500NameStyle template) + public X500NameBuilder(X500NameStyle style) { - this.template = template; + this.style = style; } + public X500NameStyle getStyle() + { + return style; + } + /** * Add an RDN based on a single OID and a string representation of its value. * @@ -41,7 +46,7 @@ public X500NameBuilder(X500NameStyle template) */ public X500NameBuilder addRDN(ASN1ObjectIdentifier oid, String value) { - this.addRDN(oid, template.stringToValue(oid, value)); + this.addRDN(oid, style.stringToValue(oid, value)); return this; } @@ -86,7 +91,7 @@ public X500NameBuilder addMultiValuedRDN(ASN1ObjectIdentifier[] oids, String[] v for (int i = 0; i != vals.length; i++) { - vals[i] = template.stringToValue(oids[i], values[i]); + vals[i] = style.stringToValue(oids[i], values[i]); } return addMultiValuedRDN(oids, vals); @@ -130,6 +135,11 @@ public X500NameBuilder addMultiValuedRDN(AttributeTypeAndValue[] attrTAndVs) * @return a new X.500 name. */ public X500Name build() + { + return new X500Name(style, buildRDNs()); + } + + public RDN[] buildRDNs() { RDN[] vals = new RDN[rdns.size()]; @@ -138,6 +148,6 @@ public X500Name build() vals[i] = (RDN)rdns.elementAt(i); } - return new X500Name(template, vals); + return vals; } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java index 6f20e2309d..abb757d28d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java @@ -68,8 +68,9 @@ public int calculateHashCode(X500Name name) } else { - hashCodeValue ^= rdns[i].getFirst().getType().hashCode(); - hashCodeValue ^= calcHashCode(rdns[i].getFirst().getValue()); + AttributeTypeAndValue first = rdns[i].getFirst(); + hashCodeValue ^= first.getType().hashCode(); + hashCodeValue ^= calcHashCode(first.getValue()); } } diff --git a/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java b/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java index 5ab27191f4..1c0367870d 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java +++ b/core/src/main/java/org/bouncycastle/asn1/x500/style/IETFUtils.java @@ -131,32 +131,30 @@ private static int convertHex(char c) public static RDN[] rDNsFromString(String name, X500NameStyle x500Style) { - X500NameTokenizer tokenizer = new X500NameTokenizer(name); X500NameBuilder builder = new X500NameBuilder(x500Style); - addRDNs(x500Style, builder, tokenizer); + addRDNs(builder, new X500NameTokenizer(name)); - // TODO There's an unnecessary clone of the RDNs array happening here - return builder.build().getRDNs(); + return builder.buildRDNs(); } - private static void addRDNs(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer) + private static void addRDNs(X500NameBuilder builder, X500NameTokenizer tokenizer) { String token; while ((token = tokenizer.nextToken()) != null) { if (token.indexOf('+') >= 0) { - addMultiValuedRDN(style, builder, new X500NameTokenizer(token, '+')); + addMultiValuedRDN(builder, new X500NameTokenizer(token, '+')); } else { - addRDN(style, builder, token); + addRDN(builder, token); } } } - private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer) + private static void addMultiValuedRDN(X500NameBuilder builder, X500NameTokenizer tokenizer) { String token = tokenizer.nextToken(); if (token == null) @@ -166,13 +164,14 @@ private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder build if (!tokenizer.hasMoreTokens()) { - addRDN(style, builder, token); + addRDN(builder, token); return; } Vector oids = new Vector(); Vector values = new Vector(); + X500NameStyle style = builder.getStyle(); do { collectAttributeTypeAndValue(style, oids, values, token); @@ -183,14 +182,14 @@ private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder build builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values)); } - private static void addRDN(X500NameStyle style, X500NameBuilder builder, String token) + private static void addRDN(X500NameBuilder builder, String token) { X500NameTokenizer tokenizer = new X500NameTokenizer(token, '='); String typeToken = nextToken(tokenizer, true); String valueToken = nextToken(tokenizer, false); - ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim()); + ASN1ObjectIdentifier oid = builder.getStyle().attrNameToOID(typeToken.trim()); String value = unescape(valueToken); builder.addRDN(oid, value); @@ -337,9 +336,10 @@ public static void appendRDN( } else { - if (rdn.getFirst() != null) + AttributeTypeAndValue first = rdn.getFirst(); + if (first != null) { - IETFUtils.appendTypeAndValue(buf, rdn.getFirst(), oidSymbols); + IETFUtils.appendTypeAndValue(buf, first, oidSymbols); } } } @@ -370,9 +370,10 @@ public static void appendRDN( } else { - if (rdn.getFirst() != null) + AttributeTypeAndValue first = rdn.getFirst(); + if (first != null) { - IETFUtils.appendTypeAndValue(buf, rdn.getFirst(), oidSymbols); + IETFUtils.appendTypeAndValue(buf, first, oidSymbols); } } } diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java b/core/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java index 53333d9532..12b9270327 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java @@ -12,18 +12,7 @@ public class AlgorithmIdentifier extends ASN1Object { - private ASN1ObjectIdentifier algorithm; - private ASN1Encodable parameters; - - public static AlgorithmIdentifier getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - return getInstance(ASN1Sequence.getInstance(obj, explicit)); - } - - public static AlgorithmIdentifier getInstance( - Object obj) + public static AlgorithmIdentifier getInstance(Object obj) { if (obj instanceof AlgorithmIdentifier) { @@ -37,6 +26,19 @@ else if (obj != null) return null; } + public static AlgorithmIdentifier getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new AlgorithmIdentifier(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); + } + + public static AlgorithmIdentifier getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new AlgorithmIdentifier(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); + } + + private ASN1ObjectIdentifier algorithm; + private ASN1Encodable parameters; + public AlgorithmIdentifier( ASN1ObjectIdentifier algorithm) { diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java index a494d62b43..9b0a88766a 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java @@ -61,7 +61,7 @@ private AttributeCertificateInfo( } else { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; start = 0; } diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java b/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java index 4773c7f863..0bbd61b3c6 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/BasicConstraints.java @@ -104,7 +104,7 @@ public BasicConstraints( int pathLenConstraint) { this.cA = ASN1Boolean.getInstance(true); - this.pathLenConstraint = new ASN1Integer(pathLenConstraint); + this.pathLenConstraint = ASN1Integer.valueOf(pathLenConstraint); } public boolean isCA() diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/NoticeReference.java b/core/src/main/java/org/bouncycastle/asn1/x509/NoticeReference.java index 5e95972185..c8aff8120f 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/NoticeReference.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/NoticeReference.java @@ -48,7 +48,7 @@ private static ASN1EncodableVector convertVector(Vector numbers) } else if (o instanceof Integer) { - di = new ASN1Integer(((Integer)o).intValue()); + di = ASN1Integer.valueOf(((Integer)o).intValue()); } else { diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java b/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java index 66716c0247..6b87cc1a68 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java @@ -87,7 +87,7 @@ private TBSCertificate( else { seqStart = -1; // field 0 is missing! - version = new ASN1Integer(0); + version = ASN1Integer.ZERO; } boolean isV1 = false; @@ -175,7 +175,7 @@ public TBSCertificate(ASN1Integer version, ASN1Integer serialNumber, AlgorithmId throw new NullPointerException("'subjectPublicKeyInfo' cannot be null"); } - this.version = version != null ? version : new ASN1Integer(0); + this.version = version != null ? version : ASN1Integer.ZERO; this.serialNumber = serialNumber; this.signature = signature; this.issuer = issuer; diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java b/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java index 3125c7b6b9..00ccdb41d9 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/TBSCertificateStructure.java @@ -86,7 +86,7 @@ public TBSCertificateStructure( else { seqStart = -1; // field 0 is missing! - version = new ASN1Integer(0); + version = ASN1Integer.ZERO; } serialNumber = ASN1Integer.getInstance(seq.getObjectAt(seqStart + 1)); diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java b/core/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java index 4d871eeb45..079ac551c7 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java @@ -22,7 +22,7 @@ */ public class V1TBSCertificateGenerator { - DERTaggedObject version = new DERTaggedObject(true, 0, new ASN1Integer(0)); + DERTaggedObject version = new DERTaggedObject(true, 0, ASN1Integer.ZERO); ASN1Integer serialNumber; AlgorithmIdentifier signature; @@ -122,7 +122,7 @@ public TBSCertificate generateTBSCertificate() throw new IllegalStateException("not all mandatory fields set in V1 TBScertificate generator"); } - return new TBSCertificate(new ASN1Integer(0), serialNumber, signature, issuer, + return new TBSCertificate(ASN1Integer.ZERO, serialNumber, signature, issuer, validity != null ? validity : new Validity(startDate, endDate), subject, subjectPublicKeyInfo, null, null, null); } diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/V2AttributeCertificateInfoGenerator.java b/core/src/main/java/org/bouncycastle/asn1/x509/V2AttributeCertificateInfoGenerator.java index b4c1693145..2d29419888 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/V2AttributeCertificateInfoGenerator.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/V2AttributeCertificateInfoGenerator.java @@ -43,8 +43,8 @@ public class V2AttributeCertificateInfoGenerator public V2AttributeCertificateInfoGenerator() { - this.version = new ASN1Integer(1); - attributes = new ASN1EncodableVector(); + this.version = ASN1Integer.ONE; + this.attributes = new ASN1EncodableVector(); } public void setHolder(Holder holder) diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/V2TBSCertListGenerator.java b/core/src/main/java/org/bouncycastle/asn1/x509/V2TBSCertListGenerator.java index 04565a47a0..afd52a9898 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/V2TBSCertListGenerator.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/V2TBSCertListGenerator.java @@ -37,7 +37,7 @@ */ public class V2TBSCertListGenerator { - private ASN1Integer version = new ASN1Integer(1); + private ASN1Integer version = ASN1Integer.ONE; private AlgorithmIdentifier signature; private X500Name issuer; private Time thisUpdate, nextUpdate=null; diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/core/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java index fea58c93b5..12fe4a1b0b 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java @@ -29,7 +29,7 @@ */ public class V3TBSCertificateGenerator { - private static final DERTaggedObject VERSION = new DERTaggedObject(true, 0, new ASN1Integer(2)); + private static final DERTaggedObject VERSION = new DERTaggedObject(true, 0, ASN1Integer.TWO); ASN1Integer serialNumber; AlgorithmIdentifier signature; @@ -212,7 +212,7 @@ public TBSCertificate generateTBSCertificate() throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator"); } - return new TBSCertificate(new ASN1Integer(2), serialNumber, signature, issuer, + return new TBSCertificate(ASN1Integer.TWO, serialNumber, signature, issuer, validity != null ? validity : new Validity(startDate, endDate), subject != null ? subject : X500Name.getInstance(new DERSequence()), subjectPublicKeyInfo, issuerUniqueID, subjectUniqueID, extensions); diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java b/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java index b43ecd3103..c597f14108 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/X509Extensions.java @@ -12,7 +12,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; /** @@ -237,7 +236,7 @@ public static X509Extensions getInstance( if (obj instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject taggedObject = ASN1TaggedObject.getContextInstance(obj); return getInstance(taggedObject.getBaseObject().toASN1Primitive()); } diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/qualified/Iso4217CurrencyCode.java b/core/src/main/java/org/bouncycastle/asn1/x509/qualified/Iso4217CurrencyCode.java index 3e18e1fe39..9fa9e2d664 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/qualified/Iso4217CurrencyCode.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/qualified/Iso4217CurrencyCode.java @@ -59,7 +59,7 @@ public Iso4217CurrencyCode( { throw new IllegalArgumentException("wrong size in numeric code : not in (" +NUMERIC_MINSIZE +".."+ NUMERIC_MAXSIZE +")"); } - obj = new ASN1Integer(numeric); + obj = ASN1Integer.valueOf(numeric); } public Iso4217CurrencyCode( diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/qualified/MonetaryValue.java b/core/src/main/java/org/bouncycastle/asn1/x509/qualified/MonetaryValue.java index ecc8c17886..51fae96d7c 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/qualified/MonetaryValue.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/qualified/MonetaryValue.java @@ -61,8 +61,8 @@ public MonetaryValue( int exponent) { this.currency = currency; - this.amount = new ASN1Integer(amount); - this.exponent = new ASN1Integer(exponent); + this.amount = ASN1Integer.valueOf(amount); + this.exponent = ASN1Integer.valueOf(exponent); } public Iso4217CurrencyCode getCurrency() diff --git a/core/src/main/java/org/bouncycastle/asn1/x509/qualified/TypeOfBiometricData.java b/core/src/main/java/org/bouncycastle/asn1/x509/qualified/TypeOfBiometricData.java index 6b9f2e2f4a..0c63846162 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x509/qualified/TypeOfBiometricData.java +++ b/core/src/main/java/org/bouncycastle/asn1/x509/qualified/TypeOfBiometricData.java @@ -55,7 +55,7 @@ public TypeOfBiometricData(int predefinedBiometricType) { if (predefinedBiometricType == PICTURE || predefinedBiometricType == HANDWRITTEN_SIGNATURE) { - obj = new ASN1Integer(predefinedBiometricType); + obj = ASN1Integer.valueOf(predefinedBiometricType); } else { diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/KeySpecificInfo.java b/core/src/main/java/org/bouncycastle/asn1/x9/KeySpecificInfo.java index 7495567cb9..a89f290b98 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x9/KeySpecificInfo.java +++ b/core/src/main/java/org/bouncycastle/asn1/x9/KeySpecificInfo.java @@ -1,12 +1,11 @@ package org.bouncycastle.asn1.x9; -import java.util.Enumeration; - import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERSequence; /** @@ -22,23 +21,6 @@ public class KeySpecificInfo extends ASN1Object { - private ASN1ObjectIdentifier algorithm; - private ASN1OctetString counter; - - /** - * Base constructor. - * - * @param algorithm algorithm identifier for the CEK. - * @param counter initial counter value for key derivation. - */ - public KeySpecificInfo( - ASN1ObjectIdentifier algorithm, - ASN1OctetString counter) - { - this.algorithm = algorithm; - this.counter = counter; - } - /** * Return a KeySpecificInfo object from the passed in object. * @@ -59,13 +41,50 @@ else if (obj != null) return null; } - private KeySpecificInfo( - ASN1Sequence seq) + public static KeySpecificInfo getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new KeySpecificInfo(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); + } + + public static KeySpecificInfo getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new KeySpecificInfo(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); + } + + private final ASN1ObjectIdentifier algorithm; + private final ASN1OctetString counter; + + private KeySpecificInfo(ASN1Sequence seq) { - Enumeration e = seq.getObjects(); + int count = seq.size(); + if (count != 2) + { + throw new IllegalArgumentException("Bad sequence size: " + count); + } + + this.algorithm = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); + this.counter = ASN1OctetString.getInstance(seq.getObjectAt(1)); + } - algorithm = (ASN1ObjectIdentifier)e.nextElement(); - counter = (ASN1OctetString)e.nextElement(); + /** + * Base constructor. + * + * @param algorithm algorithm identifier for the CEK. + * @param counter initial counter value for key derivation. + */ + public KeySpecificInfo(ASN1ObjectIdentifier algorithm, ASN1OctetString counter) + { + if (algorithm == null) + { + throw new NullPointerException("'algorithm' cannot be null"); + } + if (counter == null) + { + throw new NullPointerException("'counter' cannot be null"); + } + + this.algorithm = algorithm; + this.counter = counter; } /** diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java b/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java index 0ec5c6faf1..f5aa1a64ce 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java +++ b/core/src/main/java/org/bouncycastle/asn1/x9/OtherInfo.java @@ -1,7 +1,5 @@ package org.bouncycastle.asn1.x9; -import java.util.Enumeration; - import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; @@ -25,20 +23,6 @@ public class OtherInfo extends ASN1Object { - private KeySpecificInfo keyInfo; - private ASN1OctetString partyAInfo; - private ASN1OctetString suppPubInfo; - - public OtherInfo( - KeySpecificInfo keyInfo, - ASN1OctetString partyAInfo, - ASN1OctetString suppPubInfo) - { - this.keyInfo = keyInfo; - this.partyAInfo = partyAInfo; - this.suppPubInfo = suppPubInfo; - } - /** * Return a OtherInfo object from the passed in object. * @@ -59,26 +43,66 @@ else if (obj != null) return null; } - private OtherInfo( - ASN1Sequence seq) + public static OtherInfo getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - Enumeration e = seq.getObjects(); + return new OtherInfo(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); + } - keyInfo = KeySpecificInfo.getInstance(e.nextElement()); + public static OtherInfo getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new OtherInfo(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); + } + + private final KeySpecificInfo keyInfo; + private final ASN1OctetString partyAInfo; + private final ASN1OctetString suppPubInfo; - while (e.hasMoreElements()) + private OtherInfo(ASN1Sequence seq) + { + int count = seq.size(), pos = 0; + if (count < 2 || count > 3) { - ASN1TaggedObject o = (ASN1TaggedObject)e.nextElement(); + throw new IllegalArgumentException("Bad sequence size: " + count); + } - if (o.hasContextTag(0)) - { - partyAInfo = (ASN1OctetString)o.getExplicitBaseObject(); - } - else if (o.hasContextTag(2)) + this.keyInfo = KeySpecificInfo.getInstance(seq.getObjectAt(pos++)); + + // partyAInfo [0] OCTET STRING OPTIONAL + ASN1OctetString partyAInfo = null; + if (pos < count) + { + ASN1TaggedObject tag0 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 0); + if (tag0 != null) { - suppPubInfo = (ASN1OctetString)o.getExplicitBaseObject(); + pos++; + partyAInfo = ASN1OctetString.getTagged(tag0, true); } } + this.partyAInfo = partyAInfo; + + ASN1TaggedObject tag2 = ASN1TaggedObject.getContextInstance(seq.getObjectAt(pos++), 2); + this.suppPubInfo = ASN1OctetString.getTagged(tag2, true); + + if (pos != count) + { + throw new IllegalArgumentException("Unexpected elements in sequence"); + } + } + + public OtherInfo(KeySpecificInfo keyInfo, ASN1OctetString partyAInfo, ASN1OctetString suppPubInfo) + { + if (keyInfo == null) + { + throw new NullPointerException("'keyInfo' cannot be null"); + } + if (suppPubInfo == null) + { + throw new NullPointerException("'suppPubInfo' cannot be null"); + } + + this.keyInfo = keyInfo; + this.partyAInfo = partyAInfo; + this.suppPubInfo = suppPubInfo; } /** diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java b/core/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java index f640cac0f3..cebab707ec 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java +++ b/core/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java @@ -53,7 +53,7 @@ public ValidationParams(byte[] seed, int pgenCounter) } this.seed = new DERBitString(seed); - this.pgenCounter = new ASN1Integer(pgenCounter); + this.pgenCounter = ASN1Integer.valueOf(pgenCounter); } public ValidationParams(DERBitString seed, ASN1Integer pgenCounter) diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java b/core/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java index 194e080e31..68786f81c0 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java +++ b/core/src/main/java/org/bouncycastle/asn1/x9/X9FieldID.java @@ -65,7 +65,7 @@ public X9FieldID(int m, int k1, int k2, int k3) { this.id = characteristic_two_field; ASN1EncodableVector fieldIdParams = new ASN1EncodableVector(3); - fieldIdParams.add(new ASN1Integer(m)); + fieldIdParams.add(ASN1Integer.valueOf(m)); if (k2 == 0) { @@ -75,7 +75,7 @@ public X9FieldID(int m, int k1, int k2, int k3) } fieldIdParams.add(tpBasis); - fieldIdParams.add(new ASN1Integer(k1)); + fieldIdParams.add(ASN1Integer.valueOf(k1)); } else { @@ -86,9 +86,9 @@ public X9FieldID(int m, int k1, int k2, int k3) fieldIdParams.add(ppBasis); ASN1EncodableVector pentanomialParams = new ASN1EncodableVector(3); - pentanomialParams.add(new ASN1Integer(k1)); - pentanomialParams.add(new ASN1Integer(k2)); - pentanomialParams.add(new ASN1Integer(k3)); + pentanomialParams.add(ASN1Integer.valueOf(k1)); + pentanomialParams.add(ASN1Integer.valueOf(k2)); + pentanomialParams.add(ASN1Integer.valueOf(k3)); fieldIdParams.add(new DERSequence(pentanomialParams)); } diff --git a/core/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java index ce6f86dff4..b2416efd74 100644 --- a/core/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java +++ b/core/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java @@ -161,6 +161,7 @@ public interface X9ObjectIdentifiers *

    * Base OID: 1.3.133.16.840.63.0 */ + // TODO Seems this ought to be be 1.3.133.16.840.9.63.0, but may be in common use ASN1ObjectIdentifier x9_63_scheme = new ASN1ObjectIdentifier("1.3.133.16.840.63.0"); /** OID: 1.3.133.16.840.63.0.2 */ ASN1ObjectIdentifier dhSinglePass_stdDH_sha1kdf_scheme = x9_63_scheme.branch("2"); diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/DHKEKGenerator.java b/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/DHKEKGenerator.java index 7b7d870285..6fe9bb0e64 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/DHKEKGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/DHKEKGenerator.java @@ -2,17 +2,18 @@ import java.io.IOException; -import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.asn1.x9.KeySpecificInfo; +import org.bouncycastle.asn1.x9.OtherInfo; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.DerivationFunction; import org.bouncycastle.crypto.DerivationParameters; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.OutputLengthException; +import org.bouncycastle.crypto.io.DigestOutputStream; import org.bouncycastle.util.Pack; /** @@ -26,10 +27,9 @@ public class DHKEKGenerator private ASN1ObjectIdentifier algorithm; private int keySize; private byte[] z; - private byte[] partyAInfo; + private byte[] extraInfo; - public DHKEKGenerator( - Digest digest) + public DHKEKGenerator(Digest digest) { this.digest = digest; } @@ -41,7 +41,7 @@ public void init(DerivationParameters param) this.algorithm = params.getAlgorithm(); this.keySize = params.getKeySize(); this.z = params.getZ(); - this.partyAInfo = params.getExtraInfo(); + this.extraInfo = params.getExtraInfo(); } public Digest getDigest() @@ -57,76 +57,56 @@ public int generateBytes(byte[] out, int outOff, int len) throw new OutputLengthException("output buffer too small"); } - long oBytes = len; - int outLen = digest.getDigestSize(); + digest.reset(); + + int outputLength = len; + int digestSize = digest.getDigestSize(); - // - // this is at odds with the standard implementation, the - // maximum value should be hBits * (2^32 - 1) where hBits - // is the digest output size in bits. We can't have an - // array with a long index at the moment... - // - if (oBytes > ((2L << 32) - 1)) + // NOTE: This limit isn't reachable for current array lengths + if (outputLength > ((1L << 32) - 1) * digestSize) { throw new IllegalArgumentException("Output length too large"); } - int cThreshold = (int)((oBytes + outLen - 1) / outLen); + int counter32 = 0; + byte[] counterOctets = new byte[4]; - byte[] dig = new byte[digest.getDigestSize()]; + ASN1OctetString counter = DEROctetString.withContents(counterOctets); + KeySpecificInfo keyInfo = new KeySpecificInfo(algorithm, counter); + ASN1OctetString partyAInfo = DEROctetString.withContentsOptional(extraInfo); + ASN1OctetString suppPubInfo = DEROctetString.withContents(Pack.intToBigEndian(keySize)); + OtherInfo otherInfo = new OtherInfo(keyInfo, partyAInfo, suppPubInfo); - int counter = 1; + DigestOutputStream digestSink = new DigestOutputStream(digest); - for (int i = 0; i < cThreshold; i++) + while (len > 0) { digest.update(z, 0, z.length); - // OtherInfo - ASN1EncodableVector v1 = new ASN1EncodableVector(); - // KeySpecificInfo - ASN1EncodableVector v2 = new ASN1EncodableVector(); - - v2.add(algorithm); - v2.add(new DEROctetString(Pack.intToBigEndian(counter))); - - v1.add(new DERSequence(v2)); - - if (partyAInfo != null) - { - v1.add(new DERTaggedObject(true, 0, new DEROctetString(partyAInfo))); - } - - v1.add(new DERTaggedObject(true, 2, new DEROctetString(Pack.intToBigEndian(keySize)))); - try { - byte[] other = new DERSequence(v1).getEncoded(ASN1Encoding.DER); - - digest.update(other, 0, other.length); + // NOTE: Modify counterOctets in-situ since counter is private to this method + Pack.intToBigEndian(++counter32, counterOctets); + otherInfo.encodeTo(digestSink, ASN1Encoding.DER); } catch (IOException e) { throw new IllegalArgumentException("unable to encode parameter info: " + e.getMessage()); } - digest.doFinal(dig, 0); - - if (len > outLen) + if (len < digestSize) { - System.arraycopy(dig, 0, out, outOff, outLen); - outOff += outLen; - len -= outLen; - } - else - { - System.arraycopy(dig, 0, out, outOff, len); + byte[] tmp = new byte[digestSize]; + digest.doFinal(tmp, 0); + System.arraycopy(tmp, 0, out, outOff, len); + break; } - counter++; + digest.doFinal(out, outOff); + outOff += digestSize; + len -= digestSize; } - digest.reset(); - - return (int)oBytes; + return outputLength; } } diff --git a/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/ECDHKEKGenerator.java b/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/ECDHKEKGenerator.java index 1e50fc1034..a06d13d9a4 100644 --- a/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/ECDHKEKGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/agreement/kdf/ECDHKEKGenerator.java @@ -2,9 +2,10 @@ import java.io.IOException; -import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; @@ -58,16 +59,18 @@ public int generateBytes(byte[] out, int outOff, int len) throw new DataLengthException("output buffer too small"); } - // TODO Create an ASN.1 class for this (RFC3278) - // ECC-CMS-SharedInfo - ASN1EncodableVector v = new ASN1EncodableVector(); + AlgorithmIdentifier keyInfo = new AlgorithmIdentifier(algorithm, DERNull.INSTANCE); + ASN1OctetString suppPubInfo = DEROctetString.withContents(Pack.intToBigEndian(keySize)); - v.add(new AlgorithmIdentifier(algorithm, DERNull.INSTANCE)); - v.add(new DERTaggedObject(true, 2, new DEROctetString(Pack.intToBigEndian(keySize)))); + // TODO org.bouncycastle.asn1.cms.ecc.ECCCMSSharedInfo exists, but is located in the 'util' jar. + // TODO Should the optional DHKDFParameters.getExtraInfo be used for ECCCMSSharedInfo.entityUInfo? + ASN1Sequence eccCMSSharedInfo = new DERSequence(keyInfo, new DERTaggedObject(2, suppPubInfo)); try { - kdf.init(new KDFParameters(z, new DERSequence(v).getEncoded(ASN1Encoding.DER))); + byte[] iv = eccCMSSharedInfo.getEncoded(ASN1Encoding.DER); + + kdf.init(new KDFParameters(z, iv)); } catch (IOException e) { diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java index 09a41db9ea..7bb3643c5f 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/EthereumIESEngine.java @@ -559,13 +559,8 @@ public int generateBytes(byte[] out, int outOff, int len) long oBytes = len; int outLen = digest.getDigestSize(); - // - // this is at odds with the standard implementation, the - // maximum value should be hBits * (2^32 - 1) where hBits - // is the digest output size in bits. We can't have an - // array with a long index at the moment... - // - if (oBytes > ((2L << 32) - 1)) + // NOTE: This limit isn't reachable for current array lengths + if (oBytes > ((1L << 32) - 1) * outLen) { throw new IllegalArgumentException("output length too large"); } diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java index 5e1395dee8..32274e6cd5 100644 --- a/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/RSACoreEngine.java @@ -221,6 +221,13 @@ public BigInteger processBlock(BigInteger input) return m; } + else + { + if (key.getExponent() == null) + { + throw new IllegalStateException("null exponent, should \"org.bouncycastle.rsa.no_lenstra_check\" be enabled?"); + } + } } return input.modPow(key.getExponent(), key.getModulus()); diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/BaseKDFBytesGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/BaseKDFBytesGenerator.java index bc09ab9915..ef32d41994 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/BaseKDFBytesGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/BaseKDFBytesGenerator.java @@ -84,61 +84,47 @@ public int generateBytes(byte[] out, int outOff, int len) throws DataLengthExcep throw new OutputLengthException("output buffer too small"); } - long oBytes = len; - int outLen = digest.getDigestSize(); - - // - // this is at odds with the standard implementation, the - // maximum value should be hBits * (2^32 - 1) where hBits - // is the digest output size in bits. We can't have an - // array with a long index at the moment... - // - if (oBytes > ((2L << 32) - 1)) + digest.reset(); + + int outputLength = len; + int digestSize = digest.getDigestSize(); + + // NOTE: This limit isn't reachable for current array lengths + if (outputLength > ((1L << 32) - 1) * digestSize) { throw new IllegalArgumentException("Output length too large"); } - int cThreshold = (int)((oBytes + outLen - 1) / outLen); - - byte[] dig = new byte[digest.getDigestSize()]; - + int counter32 = counterStart; byte[] C = new byte[4]; - Pack.intToBigEndian(counterStart, C, 0); - - int counterBase = counterStart & ~0xFF; - for (int i = 0; i < cThreshold; i++) + while (len > 0) { + Pack.intToBigEndian(counter32, C); + digest.update(shared, 0, shared.length); - digest.update(C, 0, C.length); + digest.update(C, 0, 4); if (iv != null) { digest.update(iv, 0, iv.length); } - digest.doFinal(dig, 0); - - if (len > outLen) + if (len < digestSize) { - System.arraycopy(dig, 0, out, outOff, outLen); - outOff += outLen; - len -= outLen; - } - else - { - System.arraycopy(dig, 0, out, outOff, len); + byte[] tmp = new byte[digestSize]; + digest.doFinal(tmp, 0); + System.arraycopy(tmp, 0, out, outOff, len); + break; } - if (++C[3] == 0) - { - counterBase += 0x100; - Pack.intToBigEndian(counterBase, C, 0); - } - } + digest.doFinal(out, outOff); + outOff += digestSize; + len -= digestSize; - digest.reset(); + ++counter32; + } - return (int)oBytes; + return outputLength; } } diff --git a/core/src/main/java/org/bouncycastle/crypto/params/DESParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/DESParameters.java index 061d134f6f..c568001db4 100644 --- a/core/src/main/java/org/bouncycastle/crypto/params/DESParameters.java +++ b/core/src/main/java/org/bouncycastle/crypto/params/DESParameters.java @@ -1,5 +1,7 @@ package org.bouncycastle.crypto.params; +import org.bouncycastle.util.Arrays; + public class DESParameters extends KeyParameter { @@ -17,14 +19,14 @@ public DESParameters( /* * DES Key length in bytes. */ - static public final int DES_KEY_LENGTH = 8; + public static final int DES_KEY_LENGTH = 8; /* * Table of weak and semi-weak keys taken from Schneier pp281 */ - static private final int N_DES_WEAK_KEYS = 16; + private static final int N_DES_WEAK_KEYS = 16; - static private byte[] DES_weak_keys = + private static byte[] DES_weak_keys = { /* weak keys */ (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, @@ -58,27 +60,21 @@ public DESParameters( * @return true if the given DES key material is weak or semi-weak, * false otherwise. */ - public static boolean isWeakKey( - byte[] key, - int offset) + public static boolean isWeakKey(byte[] key, int offset) { - if (key.length - offset < DES_KEY_LENGTH) + if (offset > (key.length - DES_KEY_LENGTH)) { throw new IllegalArgumentException("key material too short."); } - nextkey: for (int i = 0; i < N_DES_WEAK_KEYS; i++) + for (int i = 0; i < N_DES_WEAK_KEYS; i++) { - for (int j = 0; j < DES_KEY_LENGTH; j++) + if (Arrays.constantTimeAreEqual(DES_KEY_LENGTH, key, offset, DES_weak_keys, i * DES_KEY_LENGTH)) { - if (key[j + offset] != DES_weak_keys[i * DES_KEY_LENGTH + j]) - { - continue nextkey; - } + return true; } - - return true; } + return false; } diff --git a/core/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java index 5b2d0d46a6..c6984342ac 100644 --- a/core/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java +++ b/core/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java @@ -6,7 +6,7 @@ public class DESedeParameters /* * DES-EDE Key length in bytes. */ - static public final int DES_EDE_KEY_LENGTH = 24; + public static final int DES_EDE_KEY_LENGTH = 24; public DESedeParameters( byte[] key) diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java index d2c0c069d1..e93a7d2acf 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/SM2Signer.java @@ -2,6 +2,8 @@ import java.math.BigInteger; import java.security.SecureRandom; +import java.util.logging.Level; +import java.util.logging.Logger; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; @@ -30,6 +32,8 @@ public class SM2Signer implements Signer, ECConstants { + private static final Logger LOG = Logger.getLogger(SM2Signer.class.getName()); + private static final class State { static final int UNINITIALIZED = 0; @@ -160,6 +164,10 @@ public boolean verifySignature(byte[] signature) } catch (Exception e) { + if (LOG.isLoggable(Level.FINE)) + { + LOG.log(Level.FINE, "SM2 signature verification failed due to exception", e); + } } finally { @@ -248,12 +256,20 @@ private boolean verifySignature(BigInteger r, BigInteger s) // B1 if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) { + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine("SM2 signature verification failed: r out of range"); + } return false; } // B2 if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) { + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine("SM2 signature verification failed: s out of range"); + } return false; } @@ -267,6 +283,10 @@ private boolean verifySignature(BigInteger r, BigInteger s) BigInteger t = r.add(s).mod(n); if (t.equals(ZERO)) { + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine("SM2 signature verification failed: t equals zero"); + } return false; } @@ -275,6 +295,10 @@ private boolean verifySignature(BigInteger r, BigInteger s) ECPoint x1y1 = ECAlgorithms.sumOfTwoMultiplies(ecParams.getG(), s, q, t).normalize(); if (x1y1.isInfinity()) { + if (LOG.isLoggable(Level.FINE)) + { + LOG.fine("SM2 signature verification failed: calculated point at infinity"); + } return false; } diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/StandardDSAEncoding.java b/core/src/main/java/org/bouncycastle/crypto/signers/StandardDSAEncoding.java index c92b97696f..d6a7a56943 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/StandardDSAEncoding.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/StandardDSAEncoding.java @@ -16,17 +16,9 @@ public class StandardDSAEncoding { public static final StandardDSAEncoding INSTANCE = new StandardDSAEncoding(); - public byte[] encode(BigInteger n, BigInteger r, BigInteger s) throws IOException - { - ASN1EncodableVector v = new ASN1EncodableVector(); - encodeValue(n, v, r); - encodeValue(n, v, s); - return new DERSequence(v).getEncoded(ASN1Encoding.DER); - } - public BigInteger[] decode(BigInteger n, byte[] encoding) throws IOException { - ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding); + ASN1Sequence seq = ASN1Sequence.getInstance(encoding); if (seq.size() == 2) { BigInteger r = decodeValue(n, seq, 0); @@ -42,6 +34,14 @@ public BigInteger[] decode(BigInteger n, byte[] encoding) throws IOException throw new IllegalArgumentException("Malformed signature"); } + public byte[] encode(BigInteger n, BigInteger r, BigInteger s) throws IOException + { + return new DERSequence( + encodeValue(n, r), + encodeValue(n, s) + ).getEncoded(ASN1Encoding.DER); + } + protected BigInteger checkValue(BigInteger n, BigInteger x) { if (x.signum() < 0 || (null != n && x.compareTo(n) >= 0)) @@ -57,8 +57,8 @@ protected BigInteger decodeValue(BigInteger n, ASN1Sequence s, int pos) return checkValue(n, ((ASN1Integer)s.getObjectAt(pos)).getValue()); } - protected void encodeValue(BigInteger n, ASN1EncodableVector v, BigInteger x) + protected ASN1Integer encodeValue(BigInteger n, BigInteger x) { - v.add(new ASN1Integer(checkValue(n, x))); + return new ASN1Integer(checkValue(n, x)); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/util/DerUtil.java b/core/src/main/java/org/bouncycastle/crypto/util/DerUtil.java index 324c5ae4ed..89392a87cc 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/DerUtil.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/DerUtil.java @@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Exceptions; class DerUtil { @@ -27,13 +28,7 @@ static byte[] toByteArray(ASN1Primitive primitive) } catch (final IOException e) { - throw new IllegalStateException("Cannot get encoding: " + e.getMessage()) - { - public Throwable getCause() - { - return e; - } - }; + throw Exceptions.illegalStateException("Cannot get encoding: " + e.getMessage(), e); } } } diff --git a/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java b/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java index b33a1a7036..866d1b1d53 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java @@ -78,7 +78,7 @@ else if (params instanceof DSAPrivateKeyParameters) DSAParameters dsaParams = dsaPrivKey.getParameters(); ASN1EncodableVector vec = new ASN1EncodableVector(); - vec.add(new ASN1Integer(0)); + vec.add(ASN1Integer.ZERO); vec.add(new ASN1Integer(dsaParams.getP())); vec.add(new ASN1Integer(dsaParams.getQ())); vec.add(new ASN1Integer(dsaParams.getG())); diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java index 8e94bc92c4..c2bc49fbf9 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java @@ -152,8 +152,16 @@ else if (algOID.equals(X9ObjectIdentifiers.id_dsa)) return new DSAPrivateKeyParameters(derX.getValue(), parameters); } + /* + * TODO id-ecDH (SECObjectIdentifiers.ecdh) and/or id-ecMQV (SECObjectIdentifiers.ecmqv) could be supported if + * we could properly restrict usage of the resulting key. + */ else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey)) { + /* + * TODO Consistency checks in case parameters and/or public key are specified at both the + * PrivateKeyInfo and ECPrivateKey levels? + */ ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); X962Parameters parameters = X962Parameters.getInstance(algId.getParameters().toASN1Primitive()); diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java index 0a5a1189a4..688de20138 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java @@ -81,6 +81,10 @@ public class PublicKeyFactory converters.put(X9ObjectIdentifiers.id_dsa, new DSAConverter()); converters.put(OIWObjectIdentifiers.dsaWithSHA1, new DSAConverter()); converters.put(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalConverter()); + /* + * TODO id-ecDH (SECObjectIdentifiers.ecdh) and/or id-ecMQV (SECObjectIdentifiers.ecmqv) could be supported if + * we could properly restrict usage of the resulting key. + */ converters.put(X9ObjectIdentifiers.id_ecPublicKey, new ECConverter()); converters.put(CryptoProObjectIdentifiers.gostR3410_2001, new GOST3410_2001Converter()); converters.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, new GOST3410_2012Converter()); diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/cms/CCMParameters.java b/core/src/main/java/org/bouncycastle/internal/asn1/cms/CCMParameters.java index 024b107b2d..7da93d3b2c 100644 --- a/core/src/main/java/org/bouncycastle/internal/asn1/cms/CCMParameters.java +++ b/core/src/main/java/org/bouncycastle/internal/asn1/cms/CCMParameters.java @@ -94,7 +94,7 @@ public ASN1Primitive toASN1Primitive() if (icvLen != 12) { - v.add(new ASN1Integer(icvLen)); + v.add(ASN1Integer.valueOf(icvLen)); } return new DERSequence(v); diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/cms/GCMParameters.java b/core/src/main/java/org/bouncycastle/internal/asn1/cms/GCMParameters.java index de8821162c..ed52e345a4 100644 --- a/core/src/main/java/org/bouncycastle/internal/asn1/cms/GCMParameters.java +++ b/core/src/main/java/org/bouncycastle/internal/asn1/cms/GCMParameters.java @@ -94,7 +94,7 @@ public ASN1Primitive toASN1Primitive() if (icvLen != 12) { - v.add(new ASN1Integer(icvLen)); + v.add(ASN1Integer.valueOf(icvLen)); } return new DERSequence(v); diff --git a/core/src/main/java/org/bouncycastle/internal/asn1/misc/CAST5CBCParameters.java b/core/src/main/java/org/bouncycastle/internal/asn1/misc/CAST5CBCParameters.java index 6f89a98b39..ecee140bf8 100644 --- a/core/src/main/java/org/bouncycastle/internal/asn1/misc/CAST5CBCParameters.java +++ b/core/src/main/java/org/bouncycastle/internal/asn1/misc/CAST5CBCParameters.java @@ -35,7 +35,7 @@ public CAST5CBCParameters( int keyLength) { this.iv = new DEROctetString(Arrays.clone(iv)); - this.keyLength = new ASN1Integer(keyLength); + this.keyLength = ASN1Integer.valueOf(keyLength); } private CAST5CBCParameters( diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java index 4da48dcb90..258e390179 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/CMCEPrivateKey.java @@ -120,7 +120,7 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(version)); + v.add(ASN1Integer.valueOf(version)); v.add(new DEROctetString(delta)); v.add(new DEROctetString(C)); v.add(new DEROctetString(g)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java index 380f547b87..a7feb04a35 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/FalconPrivateKey.java @@ -96,7 +96,7 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(version)); + v.add(ASN1Integer.valueOf(version)); v.add(new DEROctetString(f)); v.add(new DEROctetString(g)); v.add(new DEROctetString(F)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/ParSet.java b/core/src/main/java/org/bouncycastle/pqc/asn1/ParSet.java index 77b87200aa..fc95558fde 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/ParSet.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/ParSet.java @@ -120,14 +120,14 @@ public ASN1Primitive toASN1Primitive() for (int i = 0; i < h.length; i++) { - seqOfPSh.add(new ASN1Integer(h[i])); - seqOfPSw.add(new ASN1Integer(w[i])); - seqOfPSK.add(new ASN1Integer(k[i])); + seqOfPSh.add(ASN1Integer.valueOf(h[i])); + seqOfPSw.add(ASN1Integer.valueOf(w[i])); + seqOfPSK.add(ASN1Integer.valueOf(k[i])); } ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(t)); + v.add(ASN1Integer.valueOf(t)); v.add(new DERSequence(seqOfPSh)); v.add(new DERSequence(seqOfPSw)); v.add(new DERSequence(seqOfPSK)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java index d964d2eb49..62bfd4d79f 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/SABERPrivateKey.java @@ -104,7 +104,7 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(version)); + v.add(ASN1Integer.valueOf(version)); v.add(new DEROctetString(z)); v.add(new DEROctetString(s)); //todo optinal pubkey diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCS256KeyParams.java b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCS256KeyParams.java index 77f32a3c03..e446406458 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCS256KeyParams.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCS256KeyParams.java @@ -16,7 +16,7 @@ public class SPHINCS256KeyParams public SPHINCS256KeyParams(AlgorithmIdentifier treeDigest) { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; this.treeDigest = treeDigest; } diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java index 1de44f891b..50505aa7e0 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/SPHINCSPLUSPrivateKey.java @@ -91,7 +91,7 @@ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(version)); + v.add(ASN1Integer.valueOf(version)); v.add(new DEROctetString(skseed)); v.add(new DEROctetString(skprf)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSKeyParams.java b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSKeyParams.java index d4a4f669da..b1e34dfac1 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSKeyParams.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSKeyParams.java @@ -27,7 +27,7 @@ public class XMSSKeyParams public XMSSKeyParams(int height, AlgorithmIdentifier treeDigest) { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; this.height = height; this.treeDigest = treeDigest; } @@ -68,7 +68,7 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); - v.add(new ASN1Integer(height)); + v.add(ASN1Integer.valueOf(height)); v.add(treeDigest); return new DERSequence(v); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTKeyParams.java b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTKeyParams.java index 02579a94b8..45a237564c 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTKeyParams.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTKeyParams.java @@ -29,7 +29,7 @@ public class XMSSMTKeyParams public XMSSMTKeyParams(int height, int layers, AlgorithmIdentifier treeDigest) { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; this.height = height; this.layers = layers; this.treeDigest = treeDigest; @@ -74,11 +74,11 @@ public AlgorithmIdentifier getTreeDigest() public ASN1Primitive toASN1Primitive() { - ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector v = new ASN1EncodableVector(4); v.add(version); - v.add(new ASN1Integer(height)); - v.add(new ASN1Integer(layers)); + v.add(ASN1Integer.valueOf(height)); + v.add(ASN1Integer.valueOf(layers)); v.add(treeDigest); return new DERSequence(v); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPrivateKey.java index a9f1ecbafe..72ffb892b3 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPrivateKey.java @@ -176,23 +176,23 @@ public ASN1Primitive toASN1Primitive() if (maxIndex >= 0) { - v.add(new ASN1Integer(1)); // version 1 + v.add(ASN1Integer.ONE); // version 1 } else { - v.add(new ASN1Integer(0)); // version 0 + v.add(ASN1Integer.ZERO); // version 0 } ASN1EncodableVector vK = new ASN1EncodableVector(); - vK.add(new ASN1Integer(index)); + vK.add(ASN1Integer.valueOf(index)); vK.add(new DEROctetString(secretKeySeed)); vK.add(new DEROctetString(secretKeyPRF)); vK.add(new DEROctetString(publicSeed)); vK.add(new DEROctetString(root)); if (maxIndex >= 0) { - vK.add(new DERTaggedObject(false, 0, new ASN1Integer(maxIndex))); + vK.add(new DERTaggedObject(false, 0, ASN1Integer.valueOf(maxIndex))); } v.add(new DERSequence(vK)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPublicKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPublicKey.java index 11ff2ec39a..5c6ab202f6 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPublicKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSMTPublicKey.java @@ -68,9 +68,9 @@ public byte[] getRoot() public ASN1Primitive toASN1Primitive() { - ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector v = new ASN1EncodableVector(3); - v.add(new ASN1Integer(0)); // version + v.add(ASN1Integer.ZERO); // version v.add(new DEROctetString(publicSeed)); v.add(new DEROctetString(root)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPrivateKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPrivateKey.java index 94d2a6efa7..9107049ba7 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPrivateKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPrivateKey.java @@ -172,27 +172,27 @@ public byte[] getBdsState() public ASN1Primitive toASN1Primitive() { - ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector v = new ASN1EncodableVector(3); if (maxIndex >= 0) { - v.add(new ASN1Integer(1)); // version 1 + v.add(ASN1Integer.ONE); // version 1 } else { - v.add(new ASN1Integer(0)); // version 0 + v.add(ASN1Integer.ZERO); // version 0 } ASN1EncodableVector vK = new ASN1EncodableVector(); - vK.add(new ASN1Integer(index)); + vK.add(ASN1Integer.valueOf(index)); vK.add(new DEROctetString(secretKeySeed)); vK.add(new DEROctetString(secretKeyPRF)); vK.add(new DEROctetString(publicSeed)); vK.add(new DEROctetString(root)); if (maxIndex >= 0) { - vK.add(new DERTaggedObject(false, 0, new ASN1Integer(maxIndex))); + vK.add(new DERTaggedObject(false, 0, ASN1Integer.valueOf(maxIndex))); } v.add(new DERSequence(vK)); diff --git a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPublicKey.java b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPublicKey.java index ace4df9b0e..8885024240 100644 --- a/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPublicKey.java +++ b/core/src/main/java/org/bouncycastle/pqc/asn1/XMSSPublicKey.java @@ -68,9 +68,9 @@ public byte[] getRoot() public ASN1Primitive toASN1Primitive() { - ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector v = new ASN1EncodableVector(3); - v.add(new ASN1Integer(0)); // version + v.add(ASN1Integer.ZERO); // version v.add(new DEROctetString(publicSeed)); v.add(new DEROctetString(root)); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java index 9940495dfc..57542358d5 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/cmce/CMCEEngine.java @@ -1049,7 +1049,7 @@ private static int ctz(long in) } /* Used in mov columns*/ - static private long same_mask64(short x, short y) + private static long same_mask64(short x, short y) { long mask; diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCEngine.java index 4e4fe6676f..050c4ff682 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCEngine.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCEngine.java @@ -30,9 +30,10 @@ class HQCEngine private final int pkSize; private final GF2PolynomialCalculator gf; private final long rejectionThreshold; + private final int cipherTextBytes; - public HQCEngine(int n, int n1, int n2, int k, int g, int delta, int w, int wr, - int fft, int nmu, int pkSize, int[] generatorPoly) + HQCEngine(int n, int n1, int n2, int k, int g, int delta, int w, int wr, int fft, int nmu, int pkSize, + int[] generatorPoly) { this.n = n; this.k = k; @@ -54,6 +55,12 @@ public HQCEngine(int n, int n1, int n2, int k, int g, int delta, int w, int wr, long RED_MASK = ((1L << (n & 63)) - 1); this.gf = new GF2PolynomialCalculator(N_BYTE_64, n, RED_MASK); this.rejectionThreshold = ((1L << 24) / n) * n; + this.cipherTextBytes = N_BYTE + N1N2_BYTE + 16; + } + + int getCipherTextBytes() + { + return cipherTextBytes; } /** diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java index 6d7287c581..d59b0585cc 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMExtractor.java @@ -6,26 +6,24 @@ public class HQCKEMExtractor implements EncapsulatedSecretExtractor { - private HQCEngine engine; + private final HQCPrivateKeyParameters privateKey; + private final HQCEngine engine; - private final HQCKeyParameters key; - - public HQCKEMExtractor(HQCPrivateKeyParameters privParams) + public HQCKEMExtractor(HQCPrivateKeyParameters privateKey) { - this.key = privParams; - initCipher(key.getParameters()); - } + if (privateKey == null) + { + throw new NullPointerException("'privateKey' cannot be null"); + } - private void initCipher(HQCParameters param) - { - engine = param.getEngine(); + this.privateKey = privateKey; + this.engine = privateKey.getParameters().getEngine(); } public byte[] extractSecret(byte[] encapsulation) { byte[] session_key = new byte[64]; - HQCPrivateKeyParameters secretKey = (HQCPrivateKeyParameters)key; - byte[] sk = secretKey.getPrivateKey(); + byte[] sk = privateKey.getPrivateKey(); engine.decaps(session_key, encapsulation, sk); @@ -33,7 +31,7 @@ public byte[] extractSecret(byte[] encapsulation) } public int getEncapsulationLength() - { // Hash + salt - return key.getParameters().getN_BYTES() + key.getParameters().getN1N2_BYTES() + 16; + { + return engine.getCipherTextBytes(); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMGenerator.java index 70ddc930ea..e374930d16 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMGenerator.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCKEMGenerator.java @@ -2,6 +2,7 @@ import java.security.SecureRandom; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.EncapsulatedSecretGenerator; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; @@ -11,11 +12,11 @@ public class HQCKEMGenerator implements EncapsulatedSecretGenerator { - private final SecureRandom sr; + private final SecureRandom random; public HQCKEMGenerator(SecureRandom random) { - this.sr = random; + this.random = CryptoServicesRegistrar.getSecureRandom(random); } public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey) @@ -29,7 +30,7 @@ public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recip byte[] salt = new byte[key.getParameters().getSALT_SIZE_BYTES()]; byte[] pk = key.getPublicKey(); - engine.encaps(u, v, K, pk, salt, sr); + engine.encaps(u, v, K, pk, salt, random); byte[] cipherText = Arrays.concatenate(u, v, salt); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCParameters.java index aa9e0fb29b..0192b18361 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCParameters.java @@ -31,10 +31,10 @@ public class HQCParameters final static int PARAM_M = 8; final static int GF_MUL_ORDER = 255; - private final HQCEngine hqcEngine; + private final HQCEngine engine; - private HQCParameters(String name, int n, int n1, int n2, int k, int g, int delta, int w, int wr, - int fft, int nMu, int pkSize, int skSize, int[] generatorPoly) + private HQCParameters(String name, int n, int n1, int n2, int k, int g, int delta, int w, int wr, int fft, int nMu, + int pkSize, int skSize, int[] generatorPoly) { this.name = name; this.n = n; @@ -42,7 +42,7 @@ private HQCParameters(String name, int n, int n1, int n2, int k, int g, int delt this.n2 = n2; this.publicKeyBytes = pkSize; this.secretKeyBytes = skSize; - hqcEngine = new HQCEngine(n, n1, n2, k, g, delta, w, wr, fft, nMu, pkSize, generatorPoly); + this.engine = new HQCEngine(n, n1, n2, k, g, delta, w, wr, fft, nMu, pkSize, generatorPoly); } int getSHA512_BYTES() @@ -67,7 +67,12 @@ int getN1N2_BYTES() HQCEngine getEngine() { - return hqcEngine; + return engine; + } + + public int getEncapsulationLength() + { + return engine.getCipherTextBytes(); } public int getSessionKeySize() diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/CBD.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/CBD.java index a7df3c7fc8..d2c2799206 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/CBD.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/CBD.java @@ -1,84 +1,39 @@ package org.bouncycastle.pqc.crypto.mlkem; -final class CBD -{ +import org.bouncycastle.util.Pack; - public static void mlkemCBD(Poly r, byte[] bytes, int eta) +class CBD +{ + static void eta2(Poly r, byte[] bytes) { - long t, d; - int a, b; - - switch (eta) + for (int i = 0; i < MLKEMEngine.N / 8; i++) { - case 3: - for (int i = 0; i < MLKEMEngine.KyberN / 4; i++) - { - t = convertByteTo24BitUnsignedInt(bytes, 3 * i); - d = t & 0x00249249; - d = d + ((t >> 1) & 0x00249249); - d = d + ((t >> 2) & 0x00249249); - for (int j = 0; j < 4; j++) - { - a = (short)((d >> (6 * j + 0)) & 0x7); - b = (short)((d >> (6 * j + 3)) & 0x7); - // System.out.printf("a = %d, b = %d\n", a, b); - r.setCoeffIndex(4 * i + j, (short)(a - b)); - } - } - break; - default: - // Only for Kyber512 where eta = 2 - for (int i = 0; i < MLKEMEngine.KyberN / 8; i++) + int t = Pack.littleEndianToInt(bytes, 4 * i); + int d = t & 0x55555555; + d += (t >>> 1) & 0x55555555; + for (int j = 0; j < 8; j++) { - t = convertByteTo32BitUnsignedInt(bytes, 4 * i); // ? Problem - d = t & 0x55555555; - d = d + ((t >> 1) & 0x55555555); - for (int j = 0; j < 8; j++) - { - a = (short)((d >> (4 * j + 0)) & 0x3); - b = (short)((d >> (4 * j + eta)) & 0x3); - r.setCoeffIndex(8 * i + j, (short)(a - b)); - } + int a = (short)((d >>> (4 * j + 0)) & 0x3); + int b = (short)((d >>> (4 * j + 2)) & 0x3); + r.setCoeffIndex(8 * i + j, (short)(a - b)); } } } - /** - * Converts an Array of Bytes to a 32-bit Unsigned Integer - * Returns a 32-bit unsigned integer as a long - * - * @param x - * @return - */ - private static long convertByteTo32BitUnsignedInt(byte[] x, int offset) + static void eta3(Poly r, byte[] bytes) { - // Convert first byte to an unsigned integer - // byte x & 0xFF allows us to grab the last 8 bits - long r = (long)(x[offset] & 0xFF); - - // Perform the same operation then left bit shift to store the next 8 bits without - // altering the previous bits - r = r | (long)((long)(x[offset + 1] & 0xFF) << 8); - r = r | (long)((long)(x[offset + 2] & 0xFF) << 16); - r = r | (long)((long)(x[offset + 3] & 0xFF) << 24); - return r; - } - - /** - * Converts an Array of Bytes to a 24-bit Unsigned Integer - * Returns a 24-bit unsigned integer as a long from byte x - * - * @param x - * @return - */ - private static long convertByteTo24BitUnsignedInt(byte[] x, int offset) - { - // Refer to convertByteTo32-BitUnsignedInt for explanation - long r = (long)(x[offset] & 0xFF); - r = r | (long)((long)(x[offset + 1] & 0xFF) << 8); - r = r | (long)((long)(x[offset + 2] & 0xFF) << 16); - return r; + for (int i = 0; i < MLKEMEngine.N / 4; i++) + { + int t = Pack.littleEndianToInt24(bytes, 3 * i); + int d = t & 0x00249249; + d += (t >>> 1) & 0x00249249; + d += (t >>> 2) & 0x00249249; + for (int j = 0; j < 4; j++) + { + int a = (short)((d >>> (6 * j + 0)) & 0x7); + int b = (short)((d >>> (6 * j + 3)) & 0x7); + r.setCoeffIndex(4 * i + j, (short)(a - b)); + } + } } - - } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMEngine.java index 143501533d..3c6bc5d9d8 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMEngine.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMEngine.java @@ -2,201 +2,144 @@ import java.security.SecureRandom; +import org.bouncycastle.crypto.digests.SHA3Digest; +import org.bouncycastle.crypto.digests.SHAKEDigest; import org.bouncycastle.util.Arrays; class MLKEMEngine { - private SecureRandom random; - private final MLKEMIndCpa indCpa; // constant parameters - public final static int KyberN = 256; - public final static int KyberQ = 3329; - public final static int KyberQinv = 62209; - - public final static int KyberSymBytes = 32; // Number of bytes for Hashes and Seeds - private final static int KyberSharedSecretBytes = 32; // Number of Bytes for Shared Secret - - public final static int KyberPolyBytes = 384; - - private final static int KyberEta2 = 2; - - private final static int KyberIndCpaMsgBytes = KyberSymBytes; - - - // parameters for Kyber{k} - private final int KyberK; - private final int KyberPolyVecBytes; - private final int KyberPolyCompressedBytes; - private final int KyberPolyVecCompressedBytes; - private final int KyberEta1; - private final int KyberIndCpaPublicKeyBytes; - private final int KyberIndCpaSecretKeyBytes; - private final int KyberIndCpaBytes; - private final int KyberPublicKeyBytes; - private final int KyberSecretKeyBytes; - private final int KyberCipherTextBytes; - - // Crypto - private final int CryptoBytes; - private final int CryptoSecretKeyBytes; - private final int CryptoPublicKeyBytes; - private final int CryptoCipherTextBytes; - - private final int sessionKeyLength; - private final Symmetric symmetric; - - public Symmetric getSymmetric() - { - return symmetric; - } - public static int getKyberEta2() - { - return KyberEta2; - } + final static int N = 256; + final static int Q = 3329; + final static int Qinv = 62209; - public static int getKyberIndCpaMsgBytes() - { - return KyberIndCpaMsgBytes; - } + final static int SymBytes = 32; // Number of bytes for Hashes and Seeds + final static int SharedSecretBytes = 32; // Number of Bytes for Shared Secret - public int getCryptoCipherTextBytes() - { - return CryptoCipherTextBytes; - } - - public int getCryptoPublicKeyBytes() - { - return CryptoPublicKeyBytes; - } + final static int PolyBytes = 384; - public int getCryptoSecretKeyBytes() - { - return CryptoSecretKeyBytes; - } + final static int Eta2 = 2; - public int getCryptoBytes() - { - return CryptoBytes; - } + final static int SeedBytes = SymBytes * 2; - public int getKyberCipherTextBytes() - { - return KyberCipherTextBytes; - } + private final int K; + private final int PolyVecBytes; + private final int PolyCompressedBytes; + private final int PolyVecCompressedBytes; + private final int Eta1; + private final int IndCpaPublicKeyBytes; + private final int IndCpaSecretKeyBytes; + private final int SecretKeyBytes; + private final int CipherTextBytes; - public int getKyberSecretKeyBytes() + int getCipherTextBytes() { - return KyberSecretKeyBytes; + return CipherTextBytes; } - public int getKyberIndCpaPublicKeyBytes() + int getSecretKeyBytes() { - return KyberIndCpaPublicKeyBytes; + return SecretKeyBytes; } - - public int getKyberIndCpaSecretKeyBytes() + int getIndCpaPublicKeyBytes() { - return KyberIndCpaSecretKeyBytes; + return IndCpaPublicKeyBytes; } - public int getKyberIndCpaBytes() + int getIndCpaSecretKeyBytes() { - return KyberIndCpaBytes; + return IndCpaSecretKeyBytes; } - public int getKyberPublicKeyBytes() + int getPublicKeyBytes() { - return KyberPublicKeyBytes; + return getIndCpaPublicKeyBytes(); } - public int getKyberPolyCompressedBytes() + int getPolyCompressedBytes() { - return KyberPolyCompressedBytes; + return PolyCompressedBytes; } - public int getKyberK() + int getK() { - return KyberK; + return K; } - public int getKyberPolyVecBytes() + int getPolyVecBytes() { - return KyberPolyVecBytes; + return PolyVecBytes; } - public int getKyberPolyVecCompressedBytes() + int getPolyVecCompressedBytes() { - return KyberPolyVecCompressedBytes; + return PolyVecCompressedBytes; } - public int getKyberEta1() + int getEta1() { - return KyberEta1; + return Eta1; } - public MLKEMEngine(int k) + MLKEMEngine(int k) { - this.KyberK = k; + this.K = k; switch (k) { case 2: - KyberEta1 = 3; - KyberPolyCompressedBytes = 128; - KyberPolyVecCompressedBytes = k * 320; - sessionKeyLength = 32; + Eta1 = 3; + PolyCompressedBytes = 128; + PolyVecCompressedBytes = k * 320; break; case 3: - KyberEta1 = 2; - KyberPolyCompressedBytes = 128; - KyberPolyVecCompressedBytes = k * 320; - sessionKeyLength = 32; + Eta1 = 2; + PolyCompressedBytes = 128; + PolyVecCompressedBytes = k * 320; break; case 4: - KyberEta1 = 2; - KyberPolyCompressedBytes = 160; - KyberPolyVecCompressedBytes = k * 352; - sessionKeyLength = 32; + Eta1 = 2; + PolyCompressedBytes = 160; + PolyVecCompressedBytes = k * 352; break; default: - throw new IllegalArgumentException("K: " + k + " is not supported for Crystals Kyber"); + throw new IllegalArgumentException("K: " + k + " is not supported for ML-KEM"); } - this.KyberPolyVecBytes = k * KyberPolyBytes; - this.KyberIndCpaPublicKeyBytes = KyberPolyVecBytes + KyberSymBytes; - this.KyberIndCpaSecretKeyBytes = KyberPolyVecBytes; - this.KyberIndCpaBytes = KyberPolyVecCompressedBytes + KyberPolyCompressedBytes; - this.KyberPublicKeyBytes = KyberIndCpaPublicKeyBytes; - this.KyberSecretKeyBytes = KyberIndCpaSecretKeyBytes + KyberIndCpaPublicKeyBytes + 2 * KyberSymBytes; - this.KyberCipherTextBytes = KyberIndCpaBytes; - - // Define Crypto Params - this.CryptoBytes = KyberSharedSecretBytes; - this.CryptoSecretKeyBytes = KyberSecretKeyBytes; - this.CryptoPublicKeyBytes = KyberPublicKeyBytes; - this.CryptoCipherTextBytes = KyberCipherTextBytes; - - this.symmetric = new Symmetric.ShakeSymmetric(); + this.PolyVecBytes = k * PolyBytes; + this.IndCpaPublicKeyBytes = PolyVecBytes + SymBytes; + this.IndCpaSecretKeyBytes = PolyVecBytes; + this.CipherTextBytes = PolyVecCompressedBytes + PolyCompressedBytes; + this.SecretKeyBytes = IndCpaSecretKeyBytes + IndCpaPublicKeyBytes + 2 * SymBytes; this.indCpa = new MLKEMIndCpa(this); } - public void init(SecureRandom random) + boolean checkModulus(byte[] t) { - this.random = random; + return PolyVec.checkModulus(this, t) < 0; } - boolean checkModulus(byte[] t) + boolean checkPrivateKey(byte[] encoding) { - return PolyVec.checkModulus(this, t) < 0; + int k = getK(), k384 = k * 384, k768 = k * 768; + + if ((k768 + 96) != encoding.length) + { + throw new IllegalArgumentException("'encoding' has invalid length"); + } + + byte[] kH = new byte[SymBytes]; + hash_H(encoding, k384, k384 + 32, kH, 0); + return Arrays.constantTimeAreEqual(SymBytes, kH, 0, encoding, k768 + 32); } - public byte[][] generateKemKeyPair() + public byte[][] generateKemKeyPair(SecureRandom random) { - byte[] d = new byte[KyberSymBytes]; - byte[] z = new byte[KyberSymBytes]; + byte[] d = new byte[SymBytes]; + byte[] z = new byte[SymBytes]; random.nextBytes(d); random.nextBytes(z); @@ -208,16 +151,16 @@ public byte[][] generateKemKeyPairInternal(byte[] d, byte[] z) { byte[][] indCpaKeyPair = indCpa.generateKeyPair(d); - byte[] s = new byte[KyberIndCpaSecretKeyBytes]; + byte[] s = new byte[IndCpaSecretKeyBytes]; - System.arraycopy(indCpaKeyPair[1], 0, s, 0, KyberIndCpaSecretKeyBytes); + System.arraycopy(indCpaKeyPair[1], 0, s, 0, IndCpaSecretKeyBytes); byte[] hashedPublicKey = new byte[32]; - symmetric.hash_h(hashedPublicKey, indCpaKeyPair[0], 0); + hash_H(indCpaKeyPair[0], 0, indCpaKeyPair[0].length, hashedPublicKey, 0); - byte[] outputPublicKey = new byte[KyberIndCpaPublicKeyBytes]; - System.arraycopy(indCpaKeyPair[0], 0, outputPublicKey, 0, KyberIndCpaPublicKeyBytes); + byte[] outputPublicKey = new byte[IndCpaPublicKeyBytes]; + System.arraycopy(indCpaKeyPair[0], 0, outputPublicKey, 0, IndCpaPublicKeyBytes); return new byte[][] { Arrays.copyOfRange(outputPublicKey, 0, outputPublicKey.length - 32), @@ -229,26 +172,42 @@ public byte[][] generateKemKeyPairInternal(byte[] d, byte[] z) }; } + static void hash_G(byte[] input, byte[] output) + { + implDigest(new SHA3Digest(512), input, 0, input.length, output, 0); + } + + private static void hash_H(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) + { + implDigest(new SHA3Digest(256), inBuf, inOff, inLen, outBuf, outOff); + } + + private static void implDigest(SHA3Digest digest, byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) + { + digest.update(inBuf, inOff, inLen); + digest.doFinal(outBuf, outOff); + } + byte[][] kemEncrypt(MLKEMPublicKeyParameters publicKey, byte[] randBytes) { byte[] publicKeyInput = publicKey.getEncoded(); - byte[] buf = new byte[2 * KyberSymBytes]; - byte[] kr = new byte[2 * KyberSymBytes]; + byte[] buf = new byte[2 * SymBytes]; + byte[] kr = new byte[2 * SymBytes]; - System.arraycopy(randBytes, 0, buf, 0, KyberSymBytes); + System.arraycopy(randBytes, 0, buf, 0, SymBytes); // SHA3-256 Public Key - symmetric.hash_h(buf, publicKeyInput, KyberSymBytes); + hash_H(publicKeyInput, 0, publicKeyInput.length, buf, SymBytes); // SHA3-512( SHA3-256(RandBytes) || SHA3-256(PublicKey) ) - symmetric.hash_g(kr, buf); + hash_G(buf, kr); // IndCpa Encryption - byte[] outputCipherText = indCpa.encrypt(publicKeyInput, Arrays.copyOfRange(buf, 0, KyberSymBytes), + byte[] outputCipherText = indCpa.encrypt(publicKeyInput, Arrays.copyOfRange(buf, 0, SymBytes), Arrays.copyOfRange(kr, 32, kr.length)); - byte[] outputSharedSecret = new byte[sessionKeyLength]; + byte[] outputSharedSecret = new byte[SharedSecretBytes]; System.arraycopy(kr, 0, outputSharedSecret, 0, outputSharedSecret.length); @@ -262,32 +221,34 @@ byte[] kemDecrypt(MLKEMPrivateKeyParameters privateKey, byte[] cipherText) { byte[] secretKey = privateKey.getEncoded(); - byte[] buf = new byte[2 * KyberSymBytes], - kr = new byte[2 * KyberSymBytes]; - - byte[] publicKey = Arrays.copyOfRange(secretKey, KyberIndCpaSecretKeyBytes, secretKey.length); - - System.arraycopy(indCpa.decrypt(secretKey, cipherText), 0, buf, 0, KyberSymBytes); + byte[] buf = new byte[2 * SymBytes]; + indCpa.decrypt(secretKey, cipherText, buf); + System.arraycopy(secretKey, SecretKeyBytes - 2 * SymBytes, buf, SymBytes, SymBytes); - System.arraycopy(secretKey, KyberSecretKeyBytes - 2 * KyberSymBytes, buf, KyberSymBytes, KyberSymBytes); + byte[] kr = new byte[2 * SymBytes]; + hash_G(buf, kr); - symmetric.hash_g(kr, buf); + byte[] publicKey = Arrays.copyOfRange(secretKey, IndCpaSecretKeyBytes, secretKey.length); - byte[] implicit_rejection = new byte[KyberSymBytes + KyberCipherTextBytes]; + byte[] cmp = indCpa.encrypt(publicKey, Arrays.copyOfRange(buf, 0, SymBytes), + Arrays.copyOfRange(kr, SymBytes, kr.length)); - System.arraycopy(secretKey, KyberSecretKeyBytes - KyberSymBytes, implicit_rejection, 0, KyberSymBytes); - - System.arraycopy(cipherText, 0, implicit_rejection, KyberSymBytes, KyberCipherTextBytes); - - symmetric.kdf(implicit_rejection, implicit_rejection ); // J(z||c) + int fail = constantTimeZeroOnEqual(cipherText, cmp); - byte[] cmp = indCpa.encrypt(publicKey, Arrays.copyOfRange(buf, 0, KyberSymBytes), Arrays.copyOfRange(kr, KyberSymBytes, kr.length)); + // if ciphertexts do not match, “implicitly reject” + { + byte[] implicit_rejection = new byte[SharedSecretBytes]; - int fail = constantTimeZeroOnEqual(cipherText, cmp); + // J(z||c) + SHAKEDigest xof = new SHAKEDigest(256); + xof.update(secretKey, SecretKeyBytes - SymBytes, SymBytes); + xof.update(cipherText, 0, CipherTextBytes); + xof.doFinal(implicit_rejection, 0, SharedSecretBytes); - cmov(kr, implicit_rejection, KyberSymBytes, fail); + cmov(kr, implicit_rejection, SharedSecretBytes, fail); + } - return Arrays.copyOfRange(kr, 0, sessionKeyLength); + return Arrays.copyOfRange(kr, 0, SharedSecretBytes); } private void cmov(byte[] r, byte[] x, int xlen, int fail) diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java index a83fdc7220..f7eaa18880 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMExtractor.java @@ -21,11 +21,15 @@ public MLKEMExtractor(MLKEMPrivateKeyParameters privateKey) public byte[] extractSecret(byte[] encapsulation) { + if (encapsulation.length != this.getEncapsulationLength()) + { + throw new IllegalArgumentException("encapsulation wrong length"); + } return engine.kemDecrypt(privateKey, encapsulation); } public int getEncapsulationLength() { - return engine.getCryptoCipherTextBytes(); + return engine.getCipherTextBytes(); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMGenerator.java index 5d7db5f072..49264e3bda 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMGenerator.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMGenerator.java @@ -2,6 +2,7 @@ import java.security.SecureRandom; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.EncapsulatedSecretGenerator; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; @@ -10,18 +11,17 @@ public class MLKEMGenerator implements EncapsulatedSecretGenerator { - // the source of randomness - private final SecureRandom sr; + private final SecureRandom random; public MLKEMGenerator(SecureRandom random) { - this.sr = random; + this.random = CryptoServicesRegistrar.getSecureRandom(random); } public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey) { byte[] randBytes = new byte[32]; - sr.nextBytes(randBytes); + random.nextBytes(randBytes); return internalGenerateEncapsulated(recipientKey, randBytes); } @@ -30,7 +30,6 @@ public SecretWithEncapsulation internalGenerateEncapsulated(AsymmetricKeyParamet { MLKEMPublicKeyParameters key = (MLKEMPublicKeyParameters)recipientKey; MLKEMEngine engine = key.getParameters().getEngine(); - engine.init(sr); byte[][] kemEncrypt = engine.kemEncrypt(key, randBytes); return new SecretWithEncapsulationImpl(kemEncrypt[0], kemEncrypt[1]); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMIndCpa.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMIndCpa.java index d6747a11e7..e0a9b06960 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMIndCpa.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMIndCpa.java @@ -1,42 +1,22 @@ package org.bouncycastle.pqc.crypto.mlkem; +import org.bouncycastle.crypto.digests.SHAKEDigest; import org.bouncycastle.util.Arrays; class MLKEMIndCpa { - private final MLKEMEngine engine; - private final int kyberK; - private final int indCpaPublicKeyBytes; - private final int polyVecBytes; - private final int indCpaBytes; - private final int polyVecCompressedBytes; - private final int polyCompressedBytes; + private static final int SHAKE128_RATE = 168; + + private static final int NUM_MATRIX_BLOCKS = + (((12 * MLKEMEngine.N / 8) << 12) / MLKEMEngine.Q + SHAKE128_RATE) / SHAKE128_RATE; - private Symmetric symmetric; + private final MLKEMEngine engine; - public MLKEMIndCpa(MLKEMEngine engine) + MLKEMIndCpa(MLKEMEngine engine) { this.engine = engine; - this.kyberK = engine.getKyberK(); - this.indCpaPublicKeyBytes = engine.getKyberPublicKeyBytes(); - this.polyVecBytes = engine.getKyberPolyVecBytes(); - this.indCpaBytes = engine.getKyberIndCpaBytes(); - this.polyVecCompressedBytes = engine.getKyberPolyVecCompressedBytes(); - this.polyCompressedBytes = engine.getKyberPolyCompressedBytes(); - this.symmetric = engine.getSymmetric(); - - KyberGenerateMatrixNBlocks = - ( - ( - 12 * MLKEMEngine.KyberN - / 8 * (1 << 12) - / MLKEMEngine.KyberQ + symmetric.xofBlockBytes - ) - / symmetric.xofBlockBytes - ); } - /** * Generates IndCpa Key Pair * @@ -44,399 +24,298 @@ public MLKEMIndCpa(MLKEMEngine engine) */ byte[][] generateKeyPair(byte[] d) { - PolyVec secretKey = new PolyVec(engine), - publicKey = new PolyVec(engine), - e = new PolyVec(engine); + int K = engine.getK(); + + PolyVec secretKey = new PolyVec(K), publicKey = new PolyVec(K), e = new PolyVec(K); // (p, sigma) <- G(d || k) byte[] buf = new byte[64]; - symmetric.hash_g(buf, Arrays.append(d, (byte)kyberK)); + MLKEMEngine.hash_G(Arrays.append(d, (byte)K), buf); byte[] publicSeed = new byte[32]; // p in docs byte[] noiseSeed = new byte[32]; // sigma in docs System.arraycopy(buf, 0, publicSeed, 0, 32); System.arraycopy(buf, 32, noiseSeed, 0, 32); - byte count = (byte)0; + PolyVec[] matrixA = new PolyVec[K]; - // Helper.printByteArray(buf); + for (int i = 0; i < K; i++) + { + matrixA[i] = new PolyVec(K); + } + generateMatrixA(matrixA, publicSeed, false); - PolyVec[] aMatrix = new PolyVec[kyberK]; + SHAKEDigest xof = new SHAKEDigest(256); - int i; - for (i = 0; i < kyberK; i++) + byte nonce = 0; + if (engine.getEta1() == 2) { - aMatrix[i] = new PolyVec(engine); - } + for (int i = 0; i < K; i++) + { + secretKey.getVectorIndex(i).getNoiseEta2(xof, noiseSeed, nonce++); + } - generateMatrix(aMatrix, publicSeed, false); - - // System.out.println("aMatrix = "); - // for(i = 0; i < kyberK; i++) { - // System.out.print("["); - // for (int j = 0; j < kyberK; j++) { - // System.out.print("["); - // for (int k = 0; k < KyberEngine.KyberN; k++) { - // System.out.printf("%d ,", aMatrix[i].getVectorIndex(j).getCoeffIndex(k)); - // } - // System.out.print("], \n"); - // } - // System.out.print("]\n"); - // } - - for (i = 0; i < kyberK; i++) - { - secretKey.getVectorIndex(i).getEta1Noise(noiseSeed, count); - - // System.out.print("SecretKeyPolyVec["+i+"] = ["); - // for (int j =0; j < KyberEngine.KyberN; j++) { - // System.out.print(secretKey.getVectorIndex(i).getCoeffIndex(j) + ", "); - // } - // System.out.println("]"); - count++; + for (int i = 0; i < K; i++) + { + e.getVectorIndex(i).getNoiseEta2(xof, noiseSeed, nonce++); + } } - - for (i = 0; i < kyberK; i++) + else { - e.getVectorIndex(i).getEta1Noise(noiseSeed, count); - count++; + for (int i = 0; i < K; i++) + { + secretKey.getVectorIndex(i).getNoiseEta3(xof, noiseSeed, nonce++); + } + + for (int i = 0; i < K; i++) + { + e.getVectorIndex(i).getNoiseEta3(xof, noiseSeed, nonce++); + } } secretKey.polyVecNtt(); - // System.out.print("SecretKeyPolyVec = ["); - // for (i = 0; i < kyberK; i++) { - // System.out.print("["); - // for (int j =0; j < KyberEngine.KyberN; j++) { - // System.out.print(secretKey.getVectorIndex(i).getCoeffIndex(j) + ", "); - // } - // System.out.println("],"); - // } - // System.out.println("]"); - - e.polyVecNtt(); - for (i = 0; i < kyberK; i++) + for (int i = 0; i < K; i++) { - PolyVec.pointwiseAccountMontgomery(publicKey.getVectorIndex(i), aMatrix[i], secretKey, engine); + PolyVec.pointwiseAccountMontgomery(publicKey.getVectorIndex(i), matrixA[i], secretKey, engine); publicKey.getVectorIndex(i).convertToMont(); } - // System.out.print("PublicKey PolyVec = ["); - // Helper.printPolyVec(publicKey, kyberK); - publicKey.addPoly(e); publicKey.reducePoly(); - return new byte[][]{packPublicKey(publicKey, publicSeed), packSecretKey(secretKey)}; + return new byte[][]{ packPublicKey(publicKey, publicSeed), packSecretKey(secretKey) }; } - public byte[] encrypt(byte[] publicKeyInput, byte[] msg, byte[] coins) + void decrypt(byte[] secretKey, byte[] cipherText, byte[] m) { - int i; - byte[] seed; - byte nonce = (byte)0; - PolyVec sp = new PolyVec(engine), - publicKeyPolyVec = new PolyVec(engine), - errorPolyVector = new PolyVec(engine), - bp = new PolyVec(engine); - PolyVec[] aMatrixTranspose = new PolyVec[engine.getKyberK()]; - Poly errorPoly = new Poly(engine), - v = new Poly(engine), - k = new Poly(engine); + int K = engine.getK(); + PolyVec bp = new PolyVec(K), skpv = new PolyVec(K); + Poly v = new Poly(), mp = new Poly(); - // System.out.print("publickeyinput = "); - // Helper.printByteArray(publicKeyInput); - // System.out.println(); + unpackCipherText(bp, v, cipherText, 0); + unpackSecretKey(skpv, secretKey); - seed = unpackPublicKey(publicKeyPolyVec, publicKeyInput); + bp.polyVecNtt(); - // System.out.print("publickeyPolyVec = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(publicKeyPolyVec.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); + PolyVec.pointwiseAccountMontgomery(mp, skpv, bp, engine); - // System.out.print("seed = "); - // Helper.printByteArray(seed); - // System.out.println(); + mp.polyInverseNttToMont(); + mp.subtract(v); + mp.reduce(); + mp.toMsg(m); + } + + byte[] encrypt(byte[] publicKeyInput, byte[] msg, byte[] coins) + { + int K = engine.getK(); + + byte nonce = (byte)0; + PolyVec sp = new PolyVec(K), pkpv = new PolyVec(K), ep = new PolyVec(K), bp = new PolyVec(K); + PolyVec[] matrixATransposed = new PolyVec[engine.getK()]; + Poly errorPoly = new Poly(), v = new Poly(), k = new Poly(); + + byte[] seed = unpackPublicKey(pkpv, publicKeyInput); k.fromMsg(msg); - for (i = 0; i < kyberK; i++) + for (int i = 0; i < K; i++) { - aMatrixTranspose[i] = new PolyVec(engine); + matrixATransposed[i] = new PolyVec(K); } - generateMatrix(aMatrixTranspose, seed, true); - - // System.out.print("matrix transposed = "); - // for (i = 0; i < kyberK; i++) { - // System.out.print("["); - // for(int j = 0; j < kyberK; j++) { - // System.out.print("["); - // for (int l = 0; l < 256; l++) { - // System.out.printf("%d ,", aMatrixTranspose[i].getVectorIndex(j).getCoeffIndex(l)); - // } - // System.out.print("] ,\n"); - // } - // System.out.println("] ,"); - // } + generateMatrixA(matrixATransposed, seed, true); + SHAKEDigest xof = new SHAKEDigest(256); - for (i = 0; i < kyberK; i++) + if (engine.getEta1() == 2) { - sp.getVectorIndex(i).getEta1Noise(coins, nonce); - nonce = (byte)(nonce + (byte)1); + for (int i = 0; i < K; i++) + { + sp.getVectorIndex(i).getNoiseEta2(xof, coins, nonce++); + } + } + else + { + for (int i = 0; i < K; i++) + { + sp.getVectorIndex(i).getNoiseEta3(xof, coins, nonce++); + } } - - for (i = 0; i < kyberK; i++) + for (int i = 0; i < K; i++) { - errorPolyVector.getVectorIndex(i).getEta2Noise(coins, nonce); - nonce = (byte)(nonce + (byte)1); + ep.getVectorIndex(i).getNoiseEta2(xof, coins, nonce++); } - errorPoly.getEta2Noise(coins, nonce); + errorPoly.getNoiseEta2(xof, coins, nonce); sp.polyVecNtt(); - // System.out.print("sp = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(sp.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); - - - // System.out.print("sp = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(sp.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); - - for (i = 0; i < kyberK; i++) + for (int i = 0; i < K; i++) { - - PolyVec.pointwiseAccountMontgomery(bp.getVectorIndex(i), aMatrixTranspose[i], sp, engine); + PolyVec.pointwiseAccountMontgomery(bp.getVectorIndex(i), matrixATransposed[i], sp, engine); } - // System.out.print("bp = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(bp.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); - PolyVec.pointwiseAccountMontgomery(v, publicKeyPolyVec, sp, engine); + PolyVec.pointwiseAccountMontgomery(v, pkpv, sp, engine); bp.polyVecInverseNttToMont(); v.polyInverseNttToMont(); - bp.addPoly(errorPolyVector); - + bp.addPoly(ep); - v.addCoeffs(errorPoly); - v.addCoeffs(k); + v.add(errorPoly); + v.add(k); bp.reducePoly(); v.reduce(); - // System.out.print("bp = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(bp.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); - - - // System.out.print("v = "); - // Helper.printShortArray(v.getCoeffs()); - // System.out.println(); - - - byte[] outputCipherText = packCipherText(bp, v); - - return outputCipherText; + return packCipherText(bp, v); } private byte[] packCipherText(PolyVec b, Poly v) { - byte[] outBuf = new byte[indCpaBytes]; - System.arraycopy(b.compressPolyVec(), 0, outBuf, 0, polyVecCompressedBytes); - System.arraycopy(v.compressPoly(), 0, outBuf, polyVecCompressedBytes, polyCompressedBytes); - // System.out.print("outBuf = ["); - // Helper.printByteArray(outBuf); + int polyVecCompressedBytes = engine.getPolyVecCompressedBytes(); + + byte[] outBuf = new byte[engine.getCipherTextBytes()]; + b.compressPolyVec(outBuf, 0); + + byte[] compressedPoly; + if (engine.getK() == 4) + { + compressedPoly = v.compressPoly160(); + } + else + { + compressedPoly = v.compressPoly128(); + } + + System.arraycopy(compressedPoly, 0, outBuf, polyVecCompressedBytes, engine.getPolyCompressedBytes()); return outBuf; } - private void unpackCipherText(PolyVec b, Poly v, byte[] cipherText) + private void unpackCipherText(PolyVec b, Poly v, byte[] cBuf, int cOff) { - b.decompressPolyVec(cipherText); + b.decompressPolyVec(cBuf, cOff); + cOff += engine.getPolyVecCompressedBytes(); - v.decompressPoly(cipherText, engine.getKyberPolyVecCompressedBytes()); + if (engine.getK() == 4) + { + v.decompressPoly160(cBuf, cOff); + } + else + { + v.decompressPoly128(cBuf, cOff); + } } - public byte[] packPublicKey(PolyVec publicKeyPolyVec, byte[] seed) + byte[] packPublicKey(PolyVec publicKeyPolyVec, byte[] seed) { + int indCpaPublicKeyBytes = engine.getPublicKeyBytes(); + int polyVecBytes = engine.getPolyVecBytes(); + byte[] buf = new byte[indCpaPublicKeyBytes]; - System.arraycopy(publicKeyPolyVec.toBytes(), 0, buf, 0, polyVecBytes); - System.arraycopy(seed, 0, buf, polyVecBytes, MLKEMEngine.KyberSymBytes); + publicKeyPolyVec.toBytes(buf, 0); + System.arraycopy(seed, 0, buf, polyVecBytes, MLKEMEngine.SymBytes); return buf; } - public byte[] unpackPublicKey(PolyVec publicKeyPolyVec, byte[] publicKey) + byte[] unpackPublicKey(PolyVec publicKeyPolyVec, byte[] publicKey) { - byte[] outputSeed = new byte[MLKEMEngine.KyberSymBytes]; + int polyVecBytes = engine.getPolyVecBytes(); + + byte[] outputSeed = new byte[MLKEMEngine.SymBytes]; publicKeyPolyVec.fromBytes(publicKey); - System.arraycopy(publicKey, polyVecBytes, outputSeed, 0, MLKEMEngine.KyberSymBytes); + System.arraycopy(publicKey, polyVecBytes, outputSeed, 0, MLKEMEngine.SymBytes); return outputSeed; } - public byte[] packSecretKey(PolyVec secretKeyPolyVec) + byte[] packSecretKey(PolyVec secretKeyPolyVec) { - return secretKeyPolyVec.toBytes(); + byte[] r = new byte[engine.getPolyVecBytes()]; + secretKeyPolyVec.toBytes(r, 0); + return r; } - public void unpackSecretKey(PolyVec secretKeyPolyVec, byte[] secretKey) + void unpackSecretKey(PolyVec secretKeyPolyVec, byte[] secretKey) { secretKeyPolyVec.fromBytes(secretKey); } - public final int KyberGenerateMatrixNBlocks; - - public void generateMatrix(PolyVec[] aMatrix, byte[] seed, boolean transposed) + void generateMatrixA(PolyVec[] aMatrix, byte[] seed, boolean transpose) { - int i, j, k, ctr, off; - byte[] buf = new byte[KyberGenerateMatrixNBlocks * symmetric.xofBlockBytes + 2]; - for (i = 0; i < kyberK; i++) + int K = engine.getK(); + SHAKEDigest xof = new SHAKEDigest(128); + + byte[] buf = new byte[NUM_MATRIX_BLOCKS * SHAKE128_RATE + 2]; + for (int i = 0; i < K; i++) { - for (j = 0; j < kyberK; j++) + for (int j = 0; j < K; j++) { - if (transposed) + xof.reset(); + + xof.update(seed, 0, seed.length); + + if (transpose) { - symmetric.xofAbsorb(seed, (byte) i, (byte) j); + xof.update((byte)i); + xof.update((byte)j); } else { - symmetric.xofAbsorb(seed, (byte) j, (byte) i); + xof.update((byte)j); + xof.update((byte)i); } - symmetric.xofSqueezeBlocks(buf, 0, symmetric.xofBlockBytes * KyberGenerateMatrixNBlocks); - int buflen = KyberGenerateMatrixNBlocks * symmetric.xofBlockBytes; - ctr = rejectionSampling(aMatrix[i].getVectorIndex(j), 0, MLKEMEngine.KyberN, buf, buflen); + int buflen = NUM_MATRIX_BLOCKS * SHAKE128_RATE; + xof.doOutput(buf, 0, buflen); - while (ctr < MLKEMEngine.KyberN) + int ctr = rejectionSampling(aMatrix[i].getVectorIndex(j), 0, MLKEMEngine.N, buf, buflen); + while (ctr < MLKEMEngine.N) { - off = buflen % 3; - for (k = 0; k < off; k++) + int off = buflen % 3; + for (int k = 0; k < off; k++) { buf[k] = buf[buflen - off + k]; } - symmetric.xofSqueezeBlocks(buf, off, symmetric.xofBlockBytes * 2); - buflen = off + symmetric.xofBlockBytes; + + xof.doOutput(buf, off, SHAKE128_RATE * 2); + + buflen = off + SHAKE128_RATE; // Error in code Section Unsure - ctr += rejectionSampling(aMatrix[i].getVectorIndex(j), ctr, MLKEMEngine.KyberN - ctr, buf, buflen); + ctr += rejectionSampling(aMatrix[i].getVectorIndex(j), ctr, MLKEMEngine.N - ctr, buf, buflen); } } } - } private static int rejectionSampling(Poly outputBuffer, int coeffOff, int len, byte[] inpBuf, int inpBufLen) { - int ctr, pos; - short val0, val1; - ctr = pos = 0; + short Q = (short)MLKEMEngine.Q; + + int ctr = 0, pos = 0; while (ctr < len && pos + 3 <= inpBufLen) { - val0 = (short)(((((short)(inpBuf[pos] & 0xFF)) >> 0) | (((short)(inpBuf[pos + 1] & 0xFF)) << 8)) & 0xFFF); - val1 = (short)(((((short)(inpBuf[pos + 1] & 0xFF)) >> 4) | (((short)(inpBuf[pos + 2] & 0xFF)) << 4)) & 0xFFF); - pos = pos + 3; - if (val0 < (short)MLKEMEngine.KyberQ) + short d1 = (short)(((((short)(inpBuf[pos + 0] & 0xFF)) >> 0) | (((short)(inpBuf[pos + 1] & 0xFF)) << 8)) & 0xFFF); + short d2 = (short)(((((short)(inpBuf[pos + 1] & 0xFF)) >> 4) | (((short)(inpBuf[pos + 2] & 0xFF)) << 4)) & 0xFFF); + pos += 3; + + if (d1 < Q) { - outputBuffer.setCoeffIndex(coeffOff + ctr, (short)val0); + outputBuffer.setCoeffIndex(coeffOff + ctr, (short)d1); ctr++; } - if (ctr < len && val1 < (short)MLKEMEngine.KyberQ) + if (ctr < len && d2 < Q) { - outputBuffer.setCoeffIndex(coeffOff + ctr, (short)val1); + outputBuffer.setCoeffIndex(coeffOff + ctr, (short)d2); ctr++; } } return ctr; - } - - public byte[] decrypt(byte[] secretKey, byte[] cipherText) - { - byte[] outputMessage = new byte[MLKEMEngine.getKyberIndCpaMsgBytes()]; - - PolyVec bp = new PolyVec(engine), secretKeyPolyVec = new PolyVec(engine); - Poly v = new Poly(engine), mp = new Poly(engine); - - unpackCipherText(bp, v, cipherText); - - // System.out.print("bp = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(bp.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); - - - // System.out.print("v = "); - // Helper.printShortArray(v.getCoeffs()); - // System.out.println(); - - unpackSecretKey(secretKeyPolyVec, secretKey); - - // System.out.print("decrypt secretkey = ");; - // Helper.printByteArray(secretKey); - - // System.out.print("SecretKeyPolyVec = ["); - // for (i = 0; i < kyberK; i++) { - // System.out.print("["); - // for (int j =0; j < KyberEngine.KyberN; j++) { - // System.out.print(secretKeyPolyVec.getVectorIndex(i).getCoeffIndex(j) + ", "); - // } - // System.out.println("],"); - // } - // System.out.println("]"); - - // System.out.print("bp before ntt = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(bp.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); - - bp.polyVecNtt(); - - // System.out.print("bp after ntt = ["); - // for (i = 0; i < kyberK; i++) { - // Helper.printShortArray(bp.getVectorIndex(i).getCoeffs()); - // System.out.print("], \n"); - // } - // System.out.println("]"); - - PolyVec.pointwiseAccountMontgomery(mp, secretKeyPolyVec, bp, engine); - - - mp.polyInverseNttToMont(); - - mp.polySubtract(v); - - mp.reduce(); - - outputMessage = mp.toMsg(); - - return outputMessage; - } - } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyPairGenerator.java index 22a2f33ffb..ffad2c37b2 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyPairGenerator.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMKeyPairGenerator.java @@ -25,9 +25,7 @@ private AsymmetricCipherKeyPair genKeyPair() { MLKEMEngine engine = mlkemParams.getEngine(); - engine.init(random); - - byte[][] keyPair = engine.generateKemKeyPair(); + byte[][] keyPair = engine.generateKemKeyPair(random); MLKEMPublicKeyParameters pubKey = new MLKEMPublicKeyParameters(mlkemParams, keyPair[0], keyPair[1]); MLKEMPrivateKeyParameters privKey = new MLKEMPrivateKeyParameters(mlkemParams, keyPair[2], keyPair[3], keyPair[4], keyPair[0], keyPair[1], keyPair[5]); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMParameters.java index 0dbc69bece..5c1adccd25 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMParameters.java @@ -5,33 +5,41 @@ public class MLKEMParameters implements KEMParameters { - public static final MLKEMParameters ml_kem_512 = new MLKEMParameters("ML-KEM-512", 2, 256); - public static final MLKEMParameters ml_kem_768 = new MLKEMParameters("ML-KEM-768", 3, 256); - public static final MLKEMParameters ml_kem_1024 = new MLKEMParameters("ML-KEM-1024", 4, 256); + public static final MLKEMParameters ml_kem_512 = new MLKEMParameters("ML-KEM-512", 2); + public static final MLKEMParameters ml_kem_768 = new MLKEMParameters("ML-KEM-768", 3); + public static final MLKEMParameters ml_kem_1024 = new MLKEMParameters("ML-KEM-1024", 4); private final String name; - private final int k; - private final int sessionKeySize; + private final MLKEMEngine engine; - private MLKEMParameters(String name, int k, int sessionKeySize) + private MLKEMParameters(String name, int k) { + if (name == null) + { + throw new NullPointerException("'name' cannot be null"); + } + this.name = name; - this.k = k; - this.sessionKeySize = sessionKeySize; + this.engine = new MLKEMEngine(k); } - public String getName() + MLKEMEngine getEngine() { - return name; + return engine; + } + + public int getEncapsulationLength() + { + return engine.getCipherTextBytes(); } - public MLKEMEngine getEngine() + public String getName() { - return new MLKEMEngine(k); + return name; } public int getSessionKeySize() { - return sessionKeySize; + return 256; } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPrivateKeyParameters.java index 596bb9d864..25a7cc0267 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPrivateKeyParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPrivateKeyParameters.java @@ -34,6 +34,8 @@ public MLKEMPrivateKeyParameters(MLKEMParameters params, byte[] s, byte[] hpk, b this.rho = Arrays.clone(rho); this.seed = Arrays.clone(seed); this.prefFormat = BOTH; + + validate(); } public MLKEMPrivateKeyParameters(MLKEMParameters params, byte[] encoding) @@ -46,11 +48,11 @@ public MLKEMPrivateKeyParameters(MLKEMParameters params, byte[] encoding, MLKEMP super(true, params); MLKEMEngine eng = params.getEngine(); - if (encoding.length == MLKEMEngine.KyberSymBytes * 2) + if (encoding.length == MLKEMEngine.SeedBytes) { byte[][] keyData = eng.generateKemKeyPairInternal( - Arrays.copyOfRange(encoding, 0, MLKEMEngine.KyberSymBytes), - Arrays.copyOfRange(encoding, MLKEMEngine.KyberSymBytes, encoding.length)); + Arrays.copyOfRange(encoding, 0, MLKEMEngine.SymBytes), + Arrays.copyOfRange(encoding, MLKEMEngine.SymBytes, encoding.length)); this.s = keyData[2]; this.hpk = keyData[3]; this.nonce = keyData[4]; @@ -61,18 +63,20 @@ public MLKEMPrivateKeyParameters(MLKEMParameters params, byte[] encoding, MLKEMP else { int index = 0; - this.s = Arrays.copyOfRange(encoding, 0, eng.getKyberIndCpaSecretKeyBytes()); - index += eng.getKyberIndCpaSecretKeyBytes(); - this.t = Arrays.copyOfRange(encoding, index, index + eng.getKyberIndCpaPublicKeyBytes() - MLKEMEngine.KyberSymBytes); - index += eng.getKyberIndCpaPublicKeyBytes() - MLKEMEngine.KyberSymBytes; + this.s = Arrays.copyOfRange(encoding, 0, eng.getIndCpaSecretKeyBytes()); + index += eng.getIndCpaSecretKeyBytes(); + this.t = Arrays.copyOfRange(encoding, index, index + eng.getIndCpaPublicKeyBytes() - MLKEMEngine.SymBytes); + index += eng.getIndCpaPublicKeyBytes() - MLKEMEngine.SymBytes; this.rho = Arrays.copyOfRange(encoding, index, index + 32); index += 32; this.hpk = Arrays.copyOfRange(encoding, index, index + 32); index += 32; - this.nonce = Arrays.copyOfRange(encoding, index, index + MLKEMEngine.KyberSymBytes); + this.nonce = Arrays.copyOfRange(encoding, index, index + MLKEMEngine.SymBytes); this.seed = null; } + validate(); + if (pubKey != null) { if (!Arrays.constantTimeAreEqual(this.t, pubKey.t) || !Arrays.constantTimeAreEqual(this.rho, pubKey.rho)) @@ -95,9 +99,26 @@ private MLKEMPrivateKeyParameters(MLKEMPrivateKeyParameters params, int preferre this.nonce = params.nonce; this.seed = params.seed; this.prefFormat = preferredFormat; + + validate(); } + private void validate() + { + MLKEMEngine engine = getParameters().getEngine(); + if (!engine.checkPrivateKey(getEncoded())) + { + throw new IllegalArgumentException("'encoding' fails hash check"); + } + } + + /** @deprecated Use {@link #withPreferredFormat(int)} instead. */ public MLKEMPrivateKeyParameters getParametersWithFormat(int format) + { + return withPreferredFormat(format); + } + + public MLKEMPrivateKeyParameters withPreferredFormat(int format) { if (this.prefFormat == format) { @@ -131,7 +152,7 @@ public int getPreferredFormat() public byte[] getEncoded() { - return Arrays.concatenate(new byte[][]{ s, t, rho, hpk, nonce }); + return Arrays.concatenate(new byte[][]{s, t, rho, hpk, nonce}); } public byte[] getHPK() diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPublicKeyParameters.java index bc0152a183..c3d89a68f9 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPublicKeyParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/MLKEMPublicKeyParameters.java @@ -19,11 +19,11 @@ public MLKEMPublicKeyParameters(MLKEMParameters params, byte[] t, byte[] rho) MLKEMEngine engine = params.getEngine(); - if (t.length != engine.getKyberPolyVecBytes()) + if (t.length != engine.getPolyVecBytes()) { throw new IllegalArgumentException("'t' has invalid length"); } - if (rho.length != MLKEMEngine.KyberSymBytes) + if (rho.length != MLKEMEngine.SymBytes) { throw new IllegalArgumentException("'rho' has invalid length"); } @@ -43,13 +43,13 @@ public MLKEMPublicKeyParameters(MLKEMParameters params, byte[] encoding) MLKEMEngine engine = params.getEngine(); - if (encoding.length != engine.getKyberIndCpaPublicKeyBytes()) + if (encoding.length != engine.getIndCpaPublicKeyBytes()) { throw new IllegalArgumentException("'encoding' has invalid length"); } - this.t = Arrays.copyOfRange(encoding, 0, encoding.length - MLKEMEngine.KyberSymBytes); - this.rho = Arrays.copyOfRange(encoding, encoding.length - MLKEMEngine.KyberSymBytes, encoding.length); + this.t = Arrays.copyOfRange(encoding, 0, encoding.length - MLKEMEngine.SymBytes); + this.rho = Arrays.copyOfRange(encoding, encoding.length - MLKEMEngine.SymBytes, encoding.length); if (!engine.checkModulus(this.t)) { diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Ntt.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Ntt.java index 100647de08..1589d0dfe5 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Ntt.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Ntt.java @@ -2,8 +2,7 @@ class Ntt { - - public static final short[] nttZetas = new short[]{ + static final short[] ZETAS = new short[]{ 2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962, 2127, 1855, 1468, 573, 2004, 264, 383, 2500, 1458, 1727, 3199, 2648, 1017, 732, 608, 1787, 411, 3124, 1758, 1223, 652, 2777, 1015, 2036, 1491, 3047, @@ -15,7 +14,7 @@ class Ntt 1218, 1994, 2455, 220, 2142, 1670, 2144, 1799, 2051, 794, 1819, 2475, 2459, 478, 3221, 3021, 996, 991, 958, 1869, 1522, 1628}; - public static final short[] nttZetasInv = new short[]{ + static final short[] ZETAS_INV = new short[]{ 1701, 1807, 1460, 2371, 2338, 2333, 308, 108, 2851, 870, 854, 1510, 2535, 1278, 1530, 1185, 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, 2945, 1465, 1285, 2007, 2719, 2726, 2232, 2512, 75, 156, 3000, 2911, 2980, 872, 2685, @@ -27,74 +26,60 @@ class Ntt 829, 2946, 3065, 1325, 2756, 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171, 3127, 3042, 1907, 1836, 1517, 359, 758, 1441}; - public static short[] ntt(short[] inp) + static short mulMont(short a, short b) { - short[] r = new short[MLKEMEngine.KyberN]; - System.arraycopy(inp, 0, r, 0, r.length); - int len, start, j, k; - short t, zeta; + return Reduce.montgomeryReduce((int)(a * b)); + } - k = 1; - for (len = 128; len >= 2; len >>= 1) + static void ntt(short[] r) + { + int j, k = 1; + for (int len = 128; len >= 2; len >>= 1) { - for (start = 0; start < 256; start = j + len) + for (int start = 0; start < 256; start = j + len) { - zeta = nttZetas[k++]; + short zeta = ZETAS[k++]; for (j = start; j < start + len; ++j) { - t = factorQMulMont(zeta, r[j + len]); - r[j + len] = (short)(r[j] - t); - r[j] = (short)(r[j] + t); + short t = r[j], u = mulMont(zeta, r[j + len]); + r[j + len] = (short)(t - u); + r[j ] = (short)(t + u); } } } - return r; } - public static short[] invNtt(short[] inp) + static void invNtt(short[] r) { - short[] r = new short[MLKEMEngine.KyberN]; - System.arraycopy(inp, 0, r, 0, MLKEMEngine.KyberN); - int len, start, j, k; - short t, zeta; - k = 0; - for (len = 2; len <= 128; len <<= 1) + int j, k = 0; + for (int len = 2; len <= 128; len <<= 1) { - for (start = 0; start < 256; start = j + len) + for (int start = 0; start < 256; start = j + len) { - zeta = nttZetasInv[k++]; + short zeta = ZETAS_INV[k++]; for (j = start; j < start + len; ++j) { - t = r[j]; - r[j] = Reduce.barretReduce((short)(t + r[j + len])); - r[j + len] = (short)(t - r[j + len]); - r[j + len] = factorQMulMont(zeta, r[j + len]); - + short t = r[j], u = r[j + len]; + r[j ] = Reduce.barrettReduce((short)(t + u)); + r[j + len] = mulMont(zeta, (short)(t - u)); } } } - - for (j = 0; j < 256; ++j) + for (int i = 0; i < 256; ++i) { - r[j] = factorQMulMont(r[j], Ntt.nttZetasInv[127]); + r[i] = mulMont(r[i], ZETAS_INV[127]); } - return r; - } - - public static short factorQMulMont(short a, short b) - { - return Reduce.montgomeryReduce((int)(a * b)); } - public static void baseMult(Poly outPoly, int outIndex, short a0, short a1, short b0, short b1, short zeta) + static void baseMult(short[] r, int off, short a0, short a1, short b0, short b1, short zeta) { - short outVal0 = factorQMulMont(a1, b1); - outVal0 = factorQMulMont(outVal0, zeta); - outVal0 += factorQMulMont(a0, b0); - outPoly.setCoeffIndex(outIndex, outVal0); + short outVal0 = mulMont(a1, b1); + outVal0 = mulMont(outVal0, zeta); + outVal0 += mulMont(a0, b0); + r[off] = outVal0; - short outVal1 = factorQMulMont(a0, b1); - outVal1 += factorQMulMont(a1, b0); - outPoly.setCoeffIndex(outIndex + 1, outVal1); + short outVal1 = mulMont(a0, b1); + outVal1 += mulMont(a1, b0); + r[off + 1] = outVal1; } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Poly.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Poly.java index 2df041cfb9..b43524092c 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Poly.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Poly.java @@ -1,245 +1,207 @@ package org.bouncycastle.pqc.crypto.mlkem; +import org.bouncycastle.crypto.Xof; + class Poly { - private short[] coeffs; - private MLKEMEngine engine; - private int polyCompressedBytes; - private int eta1; - private int eta2; - - private Symmetric symmetric; - - public Poly(MLKEMEngine engine) - { - this.coeffs = new short[MLKEMEngine.KyberN]; - this.engine = engine; - polyCompressedBytes = engine.getKyberPolyCompressedBytes(); - this.eta1 = engine.getKyberEta1(); - this.eta2 = MLKEMEngine.getKyberEta2(); - this.symmetric = engine.getSymmetric(); - } + private final short[] coeffs = new short[MLKEMEngine.N]; - public short getCoeffIndex(int i) + short getCoeffIndex(int i) { - return this.coeffs[i]; + return coeffs[i]; } - public short[] getCoeffs() + short[] getCoeffs() { - return this.coeffs; + return coeffs; } - public void setCoeffIndex(int i, short val) + void setCoeffIndex(int i, short val) { - this.coeffs[i] = val; + coeffs[i] = val; } - public void setCoeffs(short[] coeffs) + void polyNtt() { - this.coeffs = coeffs; + Ntt.ntt(coeffs); + reduce(); } - public void polyNtt() + void polyInverseNttToMont() { - this.setCoeffs(Ntt.ntt(this.getCoeffs())); - this.reduce(); + Ntt.invNtt(coeffs); } - public void polyInverseNttToMont() + void reduce() { - this.setCoeffs(Ntt.invNtt(this.getCoeffs())); - } - - public void reduce() - { - int i; - for (i = 0; i < MLKEMEngine.KyberN; i++) + for (int i = 0; i < MLKEMEngine.N; i++) { - this.setCoeffIndex(i, Reduce.barretReduce(this.getCoeffIndex(i))); + coeffs[i] = Reduce.barrettReduce(coeffs[i]); } } - public static void baseMultMontgomery(Poly r, Poly a, Poly b) + static void baseMultMontgomery(Poly r, Poly a, Poly b) { - int i; - for (i = 0; i < MLKEMEngine.KyberN / 4; i++) + for (int i = 0; i < MLKEMEngine.N / 4; i++) { - Ntt.baseMult(r, 4 * i, + Ntt.baseMult(r.coeffs, 4 * i, a.getCoeffIndex(4 * i), a.getCoeffIndex(4 * i + 1), b.getCoeffIndex(4 * i), b.getCoeffIndex(4 * i + 1), - Ntt.nttZetas[64 + i]); - Ntt.baseMult(r, 4 * i + 2, + Ntt.ZETAS[64 + i]); + Ntt.baseMult(r.coeffs, 4 * i + 2, a.getCoeffIndex(4 * i + 2), a.getCoeffIndex(4 * i + 3), b.getCoeffIndex(4 * i + 2), b.getCoeffIndex(4 * i + 3), - (short)(-1 * Ntt.nttZetas[64 + i])); + (short)(-1 * Ntt.ZETAS[64 + i])); } } - public void addCoeffs(Poly b) + void add(Poly b) { - int i; - for (i = 0; i < MLKEMEngine.KyberN; i++) + for (int i = 0; i < MLKEMEngine.N; i++) { - this.setCoeffIndex(i, (short)(this.getCoeffIndex(i) + b.getCoeffIndex(i))); + coeffs[i] = (short)(coeffs[i] + b.coeffs[i]); } } - public void convertToMont() + void convertToMont() { - int i; - final short f = (short)(((long)1 << 32) % MLKEMEngine.KyberQ); - for (i = 0; i < MLKEMEngine.KyberN; i++) + final short f = (short)(((long)1 << 32) % MLKEMEngine.Q); + for (int i = 0; i < MLKEMEngine.N; i++) { this.setCoeffIndex(i, Reduce.montgomeryReduce(this.getCoeffIndex(i) * f)); } } - public byte[] compressPoly() + byte[] compressPoly128() { - int i, j; byte[] t = new byte[8]; - byte[] r = new byte[polyCompressedBytes]; + byte[] r = new byte[128]; int count = 0; - this.conditionalSubQ(); - // System.out.print("v = ["); - // Helper.printShortArray(this.coeffs); - // System.out.print("]\n"); + condSubQ(); - if (polyCompressedBytes == 128) + for (int i = 0; i < MLKEMEngine.N / 8; i++) { - for (i = 0; i < MLKEMEngine.KyberN / 8; i++) + for (int j = 0; j < 8; j++) { - for (j = 0; j < 8; j++) - { - /*t[j] = - (byte)((((((short)this.getCoeffIndex(8 * i + j)) << 4) - + - (KyberEngine.KyberQ / 2) - ) / KyberEngine.KyberQ) - & 15);*/ - // Fix for KyberSlash2: division by KyberQ above is not - // constant time. - int t_j = this.getCoeffIndex(8 * i + j); - t_j <<= 4; - t_j += 1665; - t_j *= 80635; - t_j >>= 28; - t_j &= 15; - t[j] = (byte)t_j; - } - - r[count + 0] = (byte)(t[0] | (t[1] << 4)); - r[count + 1] = (byte)(t[2] | (t[3] << 4)); - r[count + 2] = (byte)(t[4] | (t[5] << 4)); - r[count + 3] = (byte)(t[6] | (t[7] << 4)); - count += 4; + /*t[j] = + (byte)((((((short)this.getCoeffIndex(8 * i + j)) << 4) + + + (KyberEngine.KyberQ / 2) + ) / KyberEngine.KyberQ) + & 15);*/ + // Fix for KyberSlash2: division by KyberQ above is not + // constant time. + int t_j = this.getCoeffIndex(8 * i + j); + t_j <<= 4; + t_j += 1665; + t_j *= 80635; + t_j >>= 28; + t_j &= 15; + t[j] = (byte)t_j; } + + r[count + 0] = (byte)(t[0] | (t[1] << 4)); + r[count + 1] = (byte)(t[2] | (t[3] << 4)); + r[count + 2] = (byte)(t[4] | (t[5] << 4)); + r[count + 3] = (byte)(t[6] | (t[7] << 4)); + count += 4; } - else if (polyCompressedBytes == 160) + + return r; + } + + byte[] compressPoly160() + { + byte[] t = new byte[8]; + byte[] r = new byte[160]; + int count = 0; + + condSubQ(); + + for (int i = 0; i < MLKEMEngine.N / 8; i++) { - for (i = 0; i < MLKEMEngine.KyberN / 8; i++) + for (int j = 0; j < 8; j++) { - for (j = 0; j < 8; j++) - { - /*t[j] = - (byte)(((((this.getCoeffIndex(8 * i + j) << 5)) - + - (KyberEngine.KyberQ / 2) - ) / KyberEngine.KyberQ - ) & 31 - );*/ - // Fix for KyberSlash2: division by KyberQ above is not - // constant time. - int t_j = this.getCoeffIndex(8 * i + j); - t_j <<= 5; - t_j += 1664; - t_j *= 40318; - t_j >>= 27; - t_j &= 31; - t[j] = (byte)t_j; - } - r[count + 0] = (byte)((t[0] >> 0) | (t[1] << 5)); - r[count + 1] = (byte)((t[1] >> 3) | (t[2] << 2) | (t[3] << 7)); - r[count + 2] = (byte)((t[3] >> 1) | (t[4] << 4)); - r[count + 3] = (byte)((t[4] >> 4) | (t[5] << 1) | (t[6] << 6)); - r[count + 4] = (byte)((t[6] >> 2) | (t[7] << 3)); - count += 5; + /*t[j] = + (byte)(((((this.getCoeffIndex(8 * i + j) << 5)) + + + (KyberEngine.KyberQ / 2) + ) / KyberEngine.KyberQ + ) & 31 + );*/ + // Fix for KyberSlash2: division by KyberQ above is not + // constant time. + int t_j = this.getCoeffIndex(8 * i + j); + t_j <<= 5; + t_j += 1664; + t_j *= 40318; + t_j >>= 27; + t_j &= 31; + t[j] = (byte)t_j; } - } - else - { - throw new RuntimeException("PolyCompressedBytes is neither 128 or 160!"); + r[count + 0] = (byte)((t[0] >> 0) | (t[1] << 5)); + r[count + 1] = (byte)((t[1] >> 3) | (t[2] << 2) | (t[3] << 7)); + r[count + 2] = (byte)((t[3] >> 1) | (t[4] << 4)); + r[count + 3] = (byte)((t[4] >> 4) | (t[5] << 1) | (t[6] << 6)); + r[count + 4] = (byte)((t[6] >> 2) | (t[7] << 3)); + count += 5; } - // System.out.print("r = "); - // Helper.printByteArray(r); - // System.out.println(); - return r; } - public void decompressPoly(byte[] compressedPolyCipherText, int polyCipherOff) + void decompressPoly128(byte[] cBuf, int cOff) { - int i, count = polyCipherOff; - - if (engine.getKyberPolyCompressedBytes() == 128) + int pos = cOff; + for (int i = 0; i < MLKEMEngine.N / 2; i++) { - for (i = 0; i < MLKEMEngine.KyberN / 2; i++) - { - this.setCoeffIndex(2 * i + 0, (short)((((short)((compressedPolyCipherText[count] & 0xFF) & 15) * MLKEMEngine.KyberQ) + 8) >> 4)); - this.setCoeffIndex(2 * i + 1, (short)((((short)((compressedPolyCipherText[count] & 0xFF) >> 4) * MLKEMEngine.KyberQ) + 8) >> 4)); - count += 1; - } + this.setCoeffIndex(2 * i + 0, (short)((((short)((cBuf[pos] & 0xFF) & 15) * MLKEMEngine.Q) + 8) >> 4)); + this.setCoeffIndex(2 * i + 1, (short)((((short)((cBuf[pos] & 0xFF) >> 4) * MLKEMEngine.Q) + 8) >> 4)); + pos += 1; } - else if (engine.getKyberPolyCompressedBytes() == 160) + } + + void decompressPoly160(byte[] cBuf, int cOff) + { + int pos = cOff; + + byte[] t = new byte[8]; + for (int i = 0; i < MLKEMEngine.N / 8; i++) { - int j; - byte[] t = new byte[8]; - for (i = 0; i < MLKEMEngine.KyberN / 8; i++) + t[0] = (byte)((cBuf[pos + 0] & 0xFF) >> 0); + t[1] = (byte)(((cBuf[pos + 0] & 0xFF) >> 5) | ((cBuf[pos + 1] & 0xFF) << 3)); + t[2] = (byte)((cBuf[pos + 1] & 0xFF) >> 2); + t[3] = (byte)(((cBuf[pos + 1] & 0xFF) >> 7) | ((cBuf[pos + 2] & 0xFF) << 1)); + t[4] = (byte)(((cBuf[pos + 2] & 0xFF) >> 4) | ((cBuf[pos + 3] & 0xFF) << 4)); + t[5] = (byte)((cBuf[pos + 3] & 0xFF) >> 1); + t[6] = (byte)(((cBuf[pos + 3] & 0xFF) >> 6) | ((cBuf[pos + 4] & 0xFF) << 2)); + t[7] = (byte)((cBuf[pos + 4] & 0xFF) >> 3); + pos += 5; + for (int j = 0; j < 8; j++) { - t[0] = (byte)((compressedPolyCipherText[count + 0] & 0xFF) >> 0); - t[1] = (byte)(((compressedPolyCipherText[count + 0] & 0xFF) >> 5) | ((compressedPolyCipherText[count + 1] & 0xFF) << 3)); - t[2] = (byte)((compressedPolyCipherText[count + 1] & 0xFF) >> 2); - t[3] = (byte)(((compressedPolyCipherText[count + 1] & 0xFF) >> 7) | ((compressedPolyCipherText[count + 2] & 0xFF) << 1)); - t[4] = (byte)(((compressedPolyCipherText[count + 2] & 0xFF) >> 4) | ((compressedPolyCipherText[count + 3] & 0xFF) << 4)); - t[5] = (byte)((compressedPolyCipherText[count + 3] & 0xFF) >> 1); - t[6] = (byte)(((compressedPolyCipherText[count + 3] & 0xFF) >> 6) | ((compressedPolyCipherText[count + 4] & 0xFF) << 2)); - t[7] = (byte)((compressedPolyCipherText[count + 4] & 0xFF) >> 3); - count += 5; - for (j = 0; j < 8; j++) - { - this.setCoeffIndex(8 * i + j, (short)(((t[j] & 31) * MLKEMEngine.KyberQ + 16) >> 5)); - } + this.setCoeffIndex(8 * i + j, (short)(((t[j] & 31) * MLKEMEngine.Q + 16) >> 5)); } } - else - { - throw new RuntimeException("PolyCompressedBytes is neither 128 or 160!"); - } - } - public byte[] toBytes() + void toBytes(byte[] r, int off) { - conditionalSubQ(); + condSubQ(); - byte[] r = new byte[MLKEMEngine.KyberPolyBytes]; - for (int i = 0; i < MLKEMEngine.KyberN / 2; i++) + for (int i = 0; i < MLKEMEngine.N / 2; i++) { short t0 = coeffs[2 * i + 0]; short t1 = coeffs[2 * i + 1]; - r[3 * i + 0] = (byte)(t0 >> 0); - r[3 * i + 1] = (byte)((t0 >> 8) | (t1 << 4)); - r[3 * i + 2] = (byte)(t1 >> 4); + r[off + 3 * i + 0] = (byte)(t0 >> 0); + r[off + 3 * i + 1] = (byte)((t0 >> 8) | (t1 << 4)); + r[off + 3 * i + 2] = (byte)(t1 >> 4); } - return r; } - public void fromBytes(byte[] inpBytes, int inOff) + void fromBytes(byte[] inpBytes, int inOff) { - for (int i = 0; i < MLKEMEngine.KyberN / 2; ++i) + for (int i = 0; i < MLKEMEngine.N / 2; ++i) { int index = inOff + (3 * i); int a0 = inpBytes[index + 0] & 0xFF; @@ -250,18 +212,16 @@ public void fromBytes(byte[] inpBytes, int inOff) } } - public byte[] toMsg() + void toMsg(byte[] msg) { - int LOWER = MLKEMEngine.KyberQ >>> 2; - int UPPER = MLKEMEngine.KyberQ - LOWER; + int LOWER = MLKEMEngine.Q >>> 2; + int UPPER = MLKEMEngine.Q - LOWER; - byte[] outMsg = new byte[MLKEMEngine.getKyberIndCpaMsgBytes()]; + condSubQ(); - this.conditionalSubQ(); - - for (int i = 0; i < MLKEMEngine.KyberN / 8; i++) + for (int i = 0; i < MLKEMEngine.N / 8; i++) { - outMsg[i] = 0; + msg[i] = 0; for (int j = 0; j < 8; j++) { int c_j = this.getCoeffIndex(8 * i + j); @@ -270,82 +230,64 @@ public byte[] toMsg() // int t = (((c_j << 1) + (KyberEngine.KyberQ / 2)) / KyberEngine.KyberQ) & 1; int t = ((LOWER - c_j) & (c_j - UPPER)) >>> 31; - outMsg[i] |= (byte)(t << j); + msg[i] |= (byte)(t << j); } } - return outMsg; } - public void fromMsg(byte[] msg) + void fromMsg(byte[] msg) { - int i, j; - short mask; - if (msg.length != MLKEMEngine.KyberN / 8) - { - throw new RuntimeException("KYBER_INDCPA_MSGBYTES must be equal to KYBER_N/8 bytes!"); - } - for (i = 0; i < MLKEMEngine.KyberN / 8; i++) + for (int i = 0; i < MLKEMEngine.N / 8; i++) { - for (j = 0; j < 8; j++) + for (int j = 0; j < 8; j++) { - mask = (short)((-1) * (short)(((msg[i] & 0xFF) >> j) & 1)); - this.setCoeffIndex(8 * i + j, (short)(mask & (short)((MLKEMEngine.KyberQ + 1) / 2))); + short mask = (short)((-1) * (short)(((msg[i] & 0xFF) >> j) & 1)); + this.setCoeffIndex(8 * i + j, (short)(mask & (short)((MLKEMEngine.Q + 1) / 2))); } } } - public void conditionalSubQ() + void condSubQ() { - int i; - for (i = 0; i < MLKEMEngine.KyberN; i++) + for (int i = 0; i < MLKEMEngine.N; i++) { - this.setCoeffIndex(i, Reduce.conditionalSubQ(this.getCoeffIndex(i))); + coeffs[i] = Reduce.condSubQ(coeffs[i]); } } - public void getEta1Noise(byte[] seed, byte nonce) + void getNoiseEta2(Xof xof, byte[] seed, byte nonce) { - byte[] buf = new byte[MLKEMEngine.KyberN * eta1 / 4]; - symmetric.prf(buf, seed, nonce); - CBD.mlkemCBD(this, buf, eta1); + byte[] buf = new byte[2 * MLKEMEngine.N / 4]; + prf(xof, seed, nonce, buf); + CBD.eta2(this, buf); } - public void getEta2Noise(byte[] seed, byte nonce) + void getNoiseEta3(Xof xof, byte[] seed, byte nonce) { - byte[] buf = new byte[MLKEMEngine.KyberN * eta2 / 4]; - symmetric.prf(buf, seed, nonce); - CBD.mlkemCBD(this, buf, eta2); + byte[] buf = new byte[3 * MLKEMEngine.N / 4]; + prf(xof, seed, nonce, buf); + CBD.eta3(this, buf); } - public void polySubtract(Poly b) + private static void prf(Xof xof, byte[] seed, byte nonce, byte[] output) { - int i; - for (i = 0; i < MLKEMEngine.KyberN; i++) - { - this.setCoeffIndex(i, (short)(b.getCoeffIndex(i) - this.getCoeffIndex(i))); - } + xof.update(seed, 0, seed.length); + xof.update(nonce); + xof.doFinal(output, 0, output.length); } - public String toString() + void subtract(Poly b) { - StringBuilder out = new StringBuilder(); - out.append("["); - for (int i = 0; i < coeffs.length; i++) + for (int i = 0; i < MLKEMEngine.N; i++) { - out.append(coeffs[i]); - if (i != coeffs.length - 1) - { - out.append(", "); - } + coeffs[i] = (short)(b.coeffs[i] - coeffs[i]); } - out.append("]"); - return out.toString(); } static int checkModulus(byte[] a, int off) { int result = -1; - for (int i = 0; i < MLKEMEngine.KyberN / 2; ++i) + for (int i = 0; i < MLKEMEngine.N / 2; ++i) { int a0 = a[off + 3 * i + 0] & 0xFF; int a1 = a[off + 3 * i + 1] & 0xFF; diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/PolyVec.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/PolyVec.java index 9e6fa7e6bd..b2259f2de6 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/PolyVec.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/PolyVec.java @@ -2,278 +2,237 @@ class PolyVec { - Poly[] vec; - private MLKEMEngine engine; - private int kyberK; - private int polyVecBytes; + final Poly[] vec; - public PolyVec(MLKEMEngine engine) + PolyVec(int K) { - this.engine = engine; - this.kyberK = engine.getKyberK(); - this.polyVecBytes = engine.getKyberPolyVecBytes(); - - this.vec = new Poly[kyberK]; - for (int i = 0; i < kyberK; i++) + this.vec = new Poly[K]; + for (int i = 0; i < K; i++) { - vec[i] = new Poly(engine); + vec[i] = new Poly(); } } - public PolyVec() - throws Exception - { - throw new Exception("Requires Parameter"); - } - - public Poly getVectorIndex(int i) + Poly getVectorIndex(int i) { return vec[i]; } - public void polyVecNtt() + void polyVecNtt() { - int i; - for (i = 0; i < kyberK; i++) + for (int i = 0; i < vec.length; i++) { - this.getVectorIndex(i).polyNtt(); + vec[i].polyNtt(); } } - public void polyVecInverseNttToMont() + void polyVecInverseNttToMont() { - for (int i = 0; i < kyberK; i++) + for (int i = 0; i < vec.length; i++) { - this.getVectorIndex(i).polyInverseNttToMont(); + vec[i].polyInverseNttToMont(); } } - public byte[] compressPolyVec() + void compressPolyVec(byte[] rBuf, int rOff) { - int i, j, k; + int pos = rOff; - this.conditionalSubQ(); - short[] t; - byte[] r = new byte[engine.getKyberPolyVecCompressedBytes()]; - int count = 0; - if (engine.getKyberPolyVecCompressedBytes() == kyberK * 320) + condSubQ(); + + if (vec.length == 4) { - t = new short[4]; - for (i = 0; i < kyberK; i++) + // PolyVecCompressedBytes == K * 352 + + short[] t = new short[8]; + for (int i = 0; i < vec.length; i++) { - for (j = 0; j < MLKEMEngine.KyberN / 4; j++) + for (int j = 0; j < MLKEMEngine.N / 8; j++) { - for (k = 0; k < 4; k++) + for (int k = 0; k < 8; k++) { /*t[k] = (short) ( ( - ((this.getVectorIndex(i).getCoeffIndex(4 * j + k) << 10) + ((this.getVectorIndex(i).getCoeffIndex(8 * j + k) << 11) + (KyberEngine.KyberQ / 2)) / KyberEngine.KyberQ) - & 0x3ff);*/ + & 0x7ff);*/ // Fix for KyberSlash2: division by KyberQ above is not // constant time. - long t_k = this.getVectorIndex(i).getCoeffIndex(4 * j + k); - t_k <<= 10; - t_k += 1665; - t_k *= 1290167; - t_k >>= 32; - t_k &= 0x3ff; + long t_k = vec[i].getCoeffIndex(8 * j + k); + t_k <<= 11; + t_k += 1664; + t_k *= 645084; + t_k >>= 31; + t_k &= 0x7ff; t[k] = (short)t_k; } - r[count + 0] = (byte)(t[0] >> 0); - r[count + 1] = (byte)((t[0] >> 8) | (t[1] << 2)); - r[count + 2] = (byte)((t[1] >> 6) | (t[2] << 4)); - r[count + 3] = (byte)((t[2] >> 4) | (t[3] << 6)); - r[count + 4] = (byte)((t[3] >> 2)); - count += 5; + rBuf[pos + 0] = (byte)((t[0] >> 0)); + rBuf[pos + 1] = (byte)((t[0] >> 8) | (t[1] << 3)); + rBuf[pos + 2] = (byte)((t[1] >> 5) | (t[2] << 6)); + rBuf[pos + 3] = (byte)((t[2] >> 2)); + rBuf[pos + 4] = (byte)((t[2] >> 10) | (t[3] << 1)); + rBuf[pos + 5] = (byte)((t[3] >> 7) | (t[4] << 4)); + rBuf[pos + 6] = (byte)((t[4] >> 4) | (t[5] << 7)); + rBuf[pos + 7] = (byte)((t[5] >> 1)); + rBuf[pos + 8] = (byte)((t[5] >> 9) | (t[6] << 2)); + rBuf[pos + 9] = (byte)((t[6] >> 6) | (t[7] << 5)); + rBuf[pos + 10] = (byte)((t[7] >> 3)); + pos += 11; } } } - else if (engine.getKyberPolyVecCompressedBytes() == kyberK * 352) + else { - t = new short[8]; - for (i = 0; i < kyberK; i++) + // PolyVecCompressedBytes == K * 320 + + short[] t = new short[4]; + for (int i = 0; i < vec.length; i++) { - for (j = 0; j < MLKEMEngine.KyberN / 8; j++) + for (int j = 0; j < MLKEMEngine.N / 4; j++) { - for (k = 0; k < 8; k++) + for (int k = 0; k < 4; k++) { /*t[k] = (short) ( ( - ((this.getVectorIndex(i).getCoeffIndex(8 * j + k) << 11) + ((this.getVectorIndex(i).getCoeffIndex(4 * j + k) << 10) + (KyberEngine.KyberQ / 2)) / KyberEngine.KyberQ) - & 0x7ff);*/ + & 0x3ff);*/ // Fix for KyberSlash2: division by KyberQ above is not // constant time. - long t_k = this.getVectorIndex(i).getCoeffIndex(8 * j + k); - t_k <<= 11; - t_k += 1664; - t_k *= 645084; - t_k >>= 31; - t_k &= 0x7ff; + long t_k = vec[i].getCoeffIndex(4 * j + k); + t_k <<= 10; + t_k += 1665; + t_k *= 1290167; + t_k >>= 32; + t_k &= 0x3ff; t[k] = (short)t_k; } - r[count + 0] = (byte)((t[0] >> 0)); - r[count + 1] = (byte)((t[0] >> 8) | (t[1] << 3)); - r[count + 2] = (byte)((t[1] >> 5) | (t[2] << 6)); - r[count + 3] = (byte)((t[2] >> 2)); - r[count + 4] = (byte)((t[2] >> 10) | (t[3] << 1)); - r[count + 5] = (byte)((t[3] >> 7) | (t[4] << 4)); - r[count + 6] = (byte)((t[4] >> 4) | (t[5] << 7)); - r[count + 7] = (byte)((t[5] >> 1)); - r[count + 8] = (byte)((t[5] >> 9) | (t[6] << 2)); - r[count + 9] = (byte)((t[6] >> 6) | (t[7] << 5)); - r[count + 10] = (byte)((t[7] >> 3)); - count += 11; + rBuf[pos + 0] = (byte)(t[0] >> 0); + rBuf[pos + 1] = (byte)((t[0] >> 8) | (t[1] << 2)); + rBuf[pos + 2] = (byte)((t[1] >> 6) | (t[2] << 4)); + rBuf[pos + 3] = (byte)((t[2] >> 4) | (t[3] << 6)); + rBuf[pos + 4] = (byte)((t[3] >> 2)); + pos += 5; } } } - else - { - throw new RuntimeException("Kyber PolyVecCompressedBytes neither 320 * KyberK or 352 * KyberK!"); - } - return r; } - public void decompressPolyVec(byte[] compressedPolyVecCipherText) + void decompressPolyVec(byte[] cBuf, int cOff) { - int i, j, k, count = 0; + int pos = cOff; - if (engine.getKyberPolyVecCompressedBytes() == (kyberK * 320)) + if (vec.length == 4) { - short[] t = new short[4]; - for (i = 0; i < kyberK; i++) + // PolyVecCompressedBytes == K * 352 + + short[] t = new short[8]; + for (int i = 0; i < vec.length; i++) { - for (j = 0; j < MLKEMEngine.KyberN / 4; j++) + for (int j = 0; j < MLKEMEngine.N / 8; j++) { - t[0] = (short)(((compressedPolyVecCipherText[count] & 0xFF) >> 0) | (short)((compressedPolyVecCipherText[count + 1] & 0xFF) << 8)); - t[1] = (short)(((compressedPolyVecCipherText[count + 1] & 0xFF) >> 2) | (short)((compressedPolyVecCipherText[count + 2] & 0xFF) << 6)); - t[2] = (short)(((compressedPolyVecCipherText[count + 2] & 0xFF) >> 4) | (short)((compressedPolyVecCipherText[count + 3] & 0xFF) << 4)); - t[3] = (short)(((compressedPolyVecCipherText[count + 3] & 0xFF) >> 6) | (short)((compressedPolyVecCipherText[count + 4] & 0xFF) << 2)); - count += 5; - for (k = 0; k < 4; k++) + t[0] = (short)(((cBuf[pos] & 0xFF) >> 0) | ((short)(cBuf[pos + 1] & 0xFF) << 8)); + t[1] = (short)(((cBuf[pos + 1] & 0xFF) >> 3) | ((short)(cBuf[pos + 2] & 0xFF) << 5)); + t[2] = (short)(((cBuf[pos + 2] & 0xFF) >> 6) | ((short)(cBuf[pos + 3] & 0xFF) << 2) | ((short)((cBuf[pos + 4] & 0xFF) << 10))); + t[3] = (short)(((cBuf[pos + 4] & 0xFF) >> 1) | ((short)(cBuf[pos + 5] & 0xFF) << 7)); + t[4] = (short)(((cBuf[pos + 5] & 0xFF) >> 4) | ((short)(cBuf[pos + 6] & 0xFF) << 4)); + t[5] = (short)(((cBuf[pos + 6] & 0xFF) >> 7) | ((short)(cBuf[pos + 7] & 0xFF) << 1) | ((short)((cBuf[pos + 8] & 0xFF) << 9))); + t[6] = (short)(((cBuf[pos + 8] & 0xFF) >> 2) | ((short)(cBuf[pos + 9] & 0xFF) << 6)); + t[7] = (short)(((cBuf[pos + 9] & 0xFF) >> 5) | ((short)(cBuf[pos + 10] & 0xFF) << 3)); + pos += 11; + for (int k = 0; k < 8; k++) { - this.vec[i].setCoeffIndex(4 * j + k, (short)(((t[k] & 0x3FF) * MLKEMEngine.KyberQ + 512) >> 10)); + this.vec[i].setCoeffIndex(8 * j + k, (short)(((t[k] & 0x7FF) * MLKEMEngine.Q + 1024) >> 11)); } } - } - } - else if (engine.getKyberPolyVecCompressedBytes() == (kyberK * 352)) + else { - short[] t = new short[8]; - for (i = 0; i < kyberK; i++) + // PolyVecCompressedBytes == K * 320 + + short[] t = new short[4]; + for (int i = 0; i < vec.length; i++) { - for (j = 0; j < MLKEMEngine.KyberN / 8; j++) + for (int j = 0; j < MLKEMEngine.N / 4; j++) { - t[0] = (short)(((compressedPolyVecCipherText[count] & 0xFF) >> 0) | ((short)(compressedPolyVecCipherText[count + 1] & 0xFF) << 8)); - t[1] = (short)(((compressedPolyVecCipherText[count + 1] & 0xFF) >> 3) | ((short)(compressedPolyVecCipherText[count + 2] & 0xFF) << 5)); - t[2] = (short)(((compressedPolyVecCipherText[count + 2] & 0xFF) >> 6) | ((short)(compressedPolyVecCipherText[count + 3] & 0xFF) << 2) | ((short)((compressedPolyVecCipherText[count + 4] & 0xFF) << 10))); - t[3] = (short)(((compressedPolyVecCipherText[count + 4] & 0xFF) >> 1) | ((short)(compressedPolyVecCipherText[count + 5] & 0xFF) << 7)); - t[4] = (short)(((compressedPolyVecCipherText[count + 5] & 0xFF) >> 4) | ((short)(compressedPolyVecCipherText[count + 6] & 0xFF) << 4)); - t[5] = (short)(((compressedPolyVecCipherText[count + 6] & 0xFF) >> 7) | ((short)(compressedPolyVecCipherText[count + 7] & 0xFF) << 1) | ((short)((compressedPolyVecCipherText[count + 8] & 0xFF) << 9))); - t[6] = (short)(((compressedPolyVecCipherText[count + 8] & 0xFF) >> 2) | ((short)(compressedPolyVecCipherText[count + 9] & 0xFF) << 6)); - t[7] = (short)(((compressedPolyVecCipherText[count + 9] & 0xFF) >> 5) | ((short)(compressedPolyVecCipherText[count + 10] & 0xFF) << 3)); - count += 11; - for (k = 0; k < 8; k++) + t[0] = (short)(((cBuf[pos] & 0xFF) >> 0) | (short)((cBuf[pos + 1] & 0xFF) << 8)); + t[1] = (short)(((cBuf[pos + 1] & 0xFF) >> 2) | (short)((cBuf[pos + 2] & 0xFF) << 6)); + t[2] = (short)(((cBuf[pos + 2] & 0xFF) >> 4) | (short)((cBuf[pos + 3] & 0xFF) << 4)); + t[3] = (short)(((cBuf[pos + 3] & 0xFF) >> 6) | (short)((cBuf[pos + 4] & 0xFF) << 2)); + pos += 5; + for (int k = 0; k < 4; k++) { - this.vec[i].setCoeffIndex(8 * j + k, (short)(((t[k] & 0x7FF) * MLKEMEngine.KyberQ + 1024) >> 11)); + this.vec[i].setCoeffIndex(4 * j + k, (short)(((t[k] & 0x3FF) * MLKEMEngine.Q + 512) >> 10)); } } } } - else - { - throw new RuntimeException("Kyber PolyVecCompressedBytes neither 320 * KyberK or 352 * KyberK!"); - } } - public static void pointwiseAccountMontgomery(Poly out, PolyVec inp1, PolyVec inp2, MLKEMEngine engine) + static void pointwiseAccountMontgomery(Poly out, PolyVec inp1, PolyVec inp2, MLKEMEngine engine) { - int i; - Poly t = new Poly(engine); + Poly t = new Poly(); - Poly.baseMultMontgomery(out, inp1.getVectorIndex(0), inp2.getVectorIndex(0)); - for (i = 1; i < engine.getKyberK(); i++) + Poly.baseMultMontgomery(out, inp1.vec[0], inp2.vec[0]); + for (int i = 1; i < engine.getK(); i++) { - Poly.baseMultMontgomery(t, inp1.getVectorIndex(i), inp2.getVectorIndex(i)); - out.addCoeffs(t); + Poly.baseMultMontgomery(t, inp1.vec[i], inp2.vec[i]); + out.add(t); } out.reduce(); } - public void reducePoly() + void reducePoly() { - int i; - for (i = 0; i < kyberK; i++) + for (int i = 0; i < vec.length; i++) { - this.getVectorIndex(i).reduce(); + vec[i].reduce(); } } - public void addPoly(PolyVec b) + void addPoly(PolyVec b) { - int i; - for (i = 0; i < kyberK; i++) + for (int i = 0; i < vec.length; i++) { - this.getVectorIndex(i).addCoeffs(b.getVectorIndex(i)); + vec[i].add(b.vec[i]); } } - public byte[] toBytes() + void toBytes(byte[] r, int rOff) { - byte[] r = new byte[polyVecBytes]; - for (int i = 0; i < kyberK; i++) + for (int i = 0; i < vec.length; i++) { - System.arraycopy(this.vec[i].toBytes(), 0, r, i * MLKEMEngine.KyberPolyBytes, MLKEMEngine.KyberPolyBytes); + vec[i].toBytes(r, rOff + i * MLKEMEngine.PolyBytes); } - - return r; } - public void fromBytes(byte[] inputBytes) + void fromBytes(byte[] inputBytes) { - for (int i = 0; i < kyberK; i++) + for (int i = 0; i < vec.length; i++) { - this.getVectorIndex(i).fromBytes(inputBytes, i * MLKEMEngine.KyberPolyBytes); + vec[i].fromBytes(inputBytes, i * MLKEMEngine.PolyBytes); } } - public void conditionalSubQ() + private void condSubQ() { - for (int i = 0; i < kyberK; i++) + for (int i = 0; i < vec.length; i++) { - this.getVectorIndex(i).conditionalSubQ(); - } - } - - public String toString() - { - StringBuilder out = new StringBuilder(); - out.append("["); - for (int i = 0; i < kyberK; i++) - { - out.append(vec[i].toString()); - if (i != kyberK - 1) - { - out.append(", "); - } + vec[i].condSubQ(); } - out.append("]"); - return out.toString(); } static int checkModulus(MLKEMEngine engine, byte[] inputBytes) { int result = -1; - for (int i = 0, k = engine.getKyberK(); i < k; i++) + for (int i = 0, k = engine.getK(); i < k; i++) { - result &= Poly.checkModulus(inputBytes, i * MLKEMEngine.KyberPolyBytes); + result &= Poly.checkModulus(inputBytes, i * MLKEMEngine.PolyBytes); } return result; } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Reduce.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Reduce.java index be3fcbf87f..9abfba060c 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Reduce.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Reduce.java @@ -2,39 +2,33 @@ class Reduce { - - public static short montgomeryReduce(int a) + static short montgomeryReduce(int a) { - int t; - short u; - - u = (short)(a * MLKEMEngine.KyberQinv); - t = (int)(u * MLKEMEngine.KyberQ); + short u = (short)(a * MLKEMEngine.Qinv); + int t = (int)(u * MLKEMEngine.Q); t = a - t; t >>= 16; return (short)t; } - public static short barretReduce(short a) + static short barrettReduce(short a) { - short t; - long shift = (((long)1) << 26); - short v = (short)((shift + (MLKEMEngine.KyberQ / 2)) / MLKEMEngine.KyberQ); - t = (short)((v * a) >> 26); - t = (short)(t * MLKEMEngine.KyberQ); + short v = (short)(((1L << 26) + (MLKEMEngine.Q / 2)) / MLKEMEngine.Q); + short t = (short)((v * a) >> 26); + t = (short)(t * MLKEMEngine.Q); return (short)(a - t); } - public static short conditionalSubQ(short a) + static short condSubQ(short a) { - a -= MLKEMEngine.KyberQ; - a += (a >> 15) & MLKEMEngine.KyberQ; + a -= MLKEMEngine.Q; + a += (a >> 15) & MLKEMEngine.Q; return a; } // NB: We only care about the sign bit of the result: it will be 1 iff the argument was in range static int checkModulus(short a) { - return a - MLKEMEngine.KyberQ; + return a - MLKEMEngine.Q; } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Symmetric.java b/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Symmetric.java deleted file mode 100644 index 40c309dedf..0000000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/mlkem/Symmetric.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.bouncycastle.pqc.crypto.mlkem; - -import org.bouncycastle.crypto.digests.SHA3Digest; -import org.bouncycastle.crypto.digests.SHAKEDigest; - -abstract class Symmetric -{ - - final int xofBlockBytes; - - abstract void hash_h(byte[] out, byte[] in, int outOffset); - - abstract void hash_g(byte[] out, byte[] in); - - abstract void xofAbsorb(byte[] seed, byte x, byte y); - - abstract void xofSqueezeBlocks(byte[] out, int outOffset, int outLen); - - abstract void prf(byte[] out, byte[] key, byte nonce); - - abstract void kdf(byte[] out, byte[] in); - - Symmetric(int blockBytes) - { - this.xofBlockBytes = blockBytes; - } - - - static class ShakeSymmetric - extends Symmetric - { - private final SHAKEDigest xof; - private final SHA3Digest sha3Digest512; - private final SHA3Digest sha3Digest256; - private final SHAKEDigest shakeDigest; - - ShakeSymmetric() - { - super(168); - this.xof = new SHAKEDigest(128); - this.shakeDigest = new SHAKEDigest(256); - this.sha3Digest256 = new SHA3Digest(256); - this.sha3Digest512 = new SHA3Digest(512); - } - - @Override - void hash_h(byte[] out, byte[] in, int outOffset) - { - sha3Digest256.update(in, 0, in.length); - sha3Digest256.doFinal(out, outOffset); - } - - @Override - void hash_g(byte[] out, byte[] in) - { - sha3Digest512.update(in, 0, in.length); - sha3Digest512.doFinal(out, 0); - } - - @Override - void xofAbsorb(byte[] seed, byte a, byte b) - { - xof.reset(); - byte[] buf = new byte[seed.length + 2]; - System.arraycopy(seed, 0, buf, 0, seed.length); - buf[seed.length] = a; - buf[seed.length + 1] = b; - xof.update(buf, 0, seed.length + 2); - } - - @Override - void xofSqueezeBlocks(byte[] out, int outOffset, int outLen) - { - xof.doOutput(out, outOffset, outLen); - } - - @Override - void prf(byte[] out, byte[] seed, byte nonce) - { - byte[] extSeed = new byte[seed.length + 1]; - System.arraycopy(seed, 0, extSeed, 0, seed.length); - extSeed[seed.length] = nonce; - shakeDigest.update(extSeed, 0, extSeed.length); - shakeDigest.doFinal(out, 0, out.length); - } - - @Override - void kdf(byte[] out, byte[] in) - { - shakeDigest.update(in, 0, in.length); - shakeDigest.doFinal(out, 0, out.length); - } - } -} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMExtractor.java index b6b0b13b51..81f4316024 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMExtractor.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMExtractor.java @@ -81,6 +81,6 @@ private void cmov(byte[] r, byte[] x, byte b) public int getEncapsulationLength() { - return ntruPrivateKey.getParameters().getParameterSet().ntruCiphertextBytes(); + return ntruPrivateKey.getParameters().getEncapsulationLength(); } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMGenerator.java index 43d9c98219..532cf659d3 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMGenerator.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUKEMGenerator.java @@ -2,6 +2,7 @@ import java.security.SecureRandom; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.EncapsulatedSecretGenerator; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.digests.SHA3Digest; @@ -22,19 +23,9 @@ public class NTRUKEMGenerator { private final SecureRandom random; - /** - * Constructor - * - * @param random a secure random number generator - */ public NTRUKEMGenerator(SecureRandom random) { - if (random == null) - { - throw new NullPointerException("'random' cannot be null"); - } - - this.random = random; + this.random = CryptoServicesRegistrar.getSecureRandom(random); } public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey) diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java index c334f0cc8a..c5e9f343fe 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntru/NTRUParameters.java @@ -52,6 +52,11 @@ private NTRUParameters(String name, NTRUParameterSet parameterSet) this.parameterSet = parameterSet; } + public int getEncapsulationLength() + { + return getParameterSet().ntruCiphertextBytes(); + } + public String getName() { return name; diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusEngine.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusEngine.java new file mode 100644 index 0000000000..113f565188 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusEngine.java @@ -0,0 +1,942 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import org.bouncycastle.crypto.digests.SHAKEDigest; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Bytes; + +class NTRUPlusEngine +{ + private static final short QINV = 12929; + private static final short OMEGA = -886; + private static final short RINV = -682; + private static final short RSQ = 867; + private static final short Q = 3457; + private static final short Q_HALF = Q >> 1; + private static final short QPlus1_Half = (Q + 1) >> 1; + private static final short QMinus1_Half = (Q - 1) >> 1; + private static final short V = ((1 << 26) + Q_HALF) / Q; + private static final byte hash_f_domain = (byte) 0x00; + private static final byte hash_g_domain = (byte) 0x01; + private static final byte hash_h_domain = (byte) 0x02; + static final int SSBytes = 32; + + private final int n; + private final int halfN; + private final int quarterN; + private final int eighthN; + private final int blockSize; + private final int doubleBlockSize; + private final int zetaOffset; + public short polyBytes; + public short[] zetas; + private final NTRUPlusParameters params; + private final SHAKEDigest shakeDigest = new SHAKEDigest(256); + + public NTRUPlusEngine(NTRUPlusParameters params) + { + this.params = params; + this.n = params.getN(); + this.halfN = this.n >> 1; + this.quarterN = this.n >> 2; + this.eighthN = this.n >> 3; + this.blockSize = n == 864 ? 3 : 4; + this.doubleBlockSize = blockSize << 1; + this.zetaOffset = params.getZetasOffset(); + this.polyBytes = (short)params.getPublicKeyBytes(); + this.zetas = params.getZetas(); + } + + /************************************************* + * Name: genf_derand + * Description: Deterministically generates a secret polynomial f and its + * multiplicative inverse finv in the NTT domain. + * Returns 0 on success; non-zero if f is not invertible in the NTT domain. + **************************************************/ + public int genf_derand(short[] f, short[] finv, byte[] coins) + { + byte[] buf = new byte[quarterN]; + + shake256(buf, 0, buf.length, coins, 32); + + poly_cbd1(f, buf, 0); + poly_triple(f, f); + f[0] += 1; + + poly_ntt(f); + + return poly_baseinv(finv, f); + } + + /************************************************* + * Name: poly_cbd1 + * Description: Sample a polynomial deterministically from a random, + * with output polynomial close to centered binomial distribution + **************************************************/ + private void poly_cbd1(short[] r, byte[] buf, int bufPos) + { + for (int i = 0, pos = 0; i < eighthN; i++, pos += 8) + { + int t1 = buf[bufPos + i] & 0xFF; // Convert to unsigned + int t2 = buf[bufPos + i + eighthN] & 0xFF; + + for (int j = 0; j < 8; j++) + { + r[pos + j] = (short)((t1 & 0x1) - (t2 & 0x1)); + t1 >>= 1; + t2 >>= 1; + } + } + } + + /************************************************* + * Name: poly_triple + * Description: Multiply polynomial by 3; no modular reduction is performed + **************************************************/ + public void poly_triple(short[] r, short[] a) + { + for (int i = 0; i < n; ++i) + { + r[i] = (short)(3 * a[i]); + } + } + + /** + * Number-theoretic transform (NTT) in R_q. + * Transforms the coefficient representation into NTT representation. + *

    + * This merged function supports N=768 (4-coefficient blocks), + * N=864 (3-coefficient blocks), and N=1152 (4-coefficient blocks). + * + * @param r Output vector in NTT representation + */ + private void poly_ntt(short[] r) + { + short t1, t2, t3; + short zeta1, zeta2; + int k = 1; + + zeta1 = zetas[k++]; + + for (int i = 0, pos = halfN; i < halfN; i++, pos++) + { + t1 = fqmul(zeta1, r[pos]); + r[pos] = (short)(r[i] + r[pos] - t1); + r[i] = (short)(r[i] + t1); + } + int baseStep = params.getBaseStep(); + int minStep = params.getMinStep(); + for (int step = n / 6; step >= (baseStep << 1); step /= 3) + { + int twoSteps = step << 1; + int threeSteps = twoSteps + step; + for (int start = 0; start < n; start += threeSteps) + { + zeta1 = zetas[k++]; + zeta2 = zetas[k++]; + + for (int i = start, pos1 = start + step, pos2 = start + twoSteps; i < start + step; i++, pos1++, pos2++) + { + t1 = fqmul(zeta1, r[pos1]); + t2 = fqmul(zeta2, r[pos2]); + t3 = fqmul(OMEGA, (short)(t1 - t2)); + + r[pos2] = (short)(r[i] - t1 - t3); + r[pos1] = (short)(r[i] - t2 + t3); + r[i] = (short)(r[i] + t1 + t2); + } + } + } + + // Final butterflies: step from 24 down to 3 + for (int step = baseStep; step >= minStep; step >>= 1) + { + for (int start = 0; start < n; start += (step << 1)) + { + zeta1 = zetas[k++]; + + for (int i = start, pos = start + step; i < start + step; i++, pos++) + { + t1 = fqmul(zeta1, r[pos]); + r[pos] = barrett_reduce((short)(r[i] - t1)); + r[i] = barrett_reduce((short)(r[i] + t1)); + } + } + } + } + + /************************************************* + * Name: fqmul + * Description: Multiplication followed by Montgomery reduction. + * Returns: 16-bit integer congruent to a*b*R^-1 mod q. + **************************************************/ + public short fqmul(short a, short b) + { + return montgomery_reduce((int)a * b); + } + + /************************************************* + * Name: montgomery_reduce + * Description: Montgomery reduction; given a 32-bit integer a, computes + * a 16-bit integer congruent to a * R^-1 mod q, + * where R = 2^16. + **************************************************/ + public short montgomery_reduce(int a) + { + return (short)((a - (short)(a * QINV) * Q) >> 16); + } + + /************************************************* + * Name: barrett_reduce + * Description: Barrett reduction; given a 16-bit integer a, computes a + * centered representative congruent to a mod q. + **************************************************/ + public short barrett_reduce(short a) + { + return (short)(a - ((V * a + (1 << 25)) >> 26) * Q); + } + + /************************************************* + * Name: poly_baseinv + * Description: Inversion of polynomial in NTT domain + **************************************************/ + private int poly_baseinv(short[] r, short[] a) + { + if (n == 864) + { + // Special handling for N=864 with 3-coefficient blocks + for (int i = 0, pos = 0, zetaOff = zetaOffset; i < n / 6; ++i, pos += 6, zetaOff++) + { + // Use baseinv3 for 3-coefficient blocks + if (baseinv3(r, pos, a, pos, zetas[zetaOff]) == 1) + { + Arrays.fill(r, (short)0); + return 1; + } + + if (baseinv3(r, pos + 3, a, pos + 3, (short)-zetas[zetaOff]) == 1) + { + Arrays.fill(r, (short)0); + return 1; + } + } + } + else + { + // Use existing logic for N=768 and N=1152 + for (int i = 0, pos = 0, zetaOff = zetaOffset; i < eighthN; ++i, pos += 8, zetaOff++) + { + if (baseinv(r, pos, a, pos, zetas[zetaOff]) == 1) + { + Arrays.fill(r, (short)0); + return 1; + } + + if (baseinv(r, pos + 4, a, pos + 4, (short)-zetas[zetaOff]) == 1) + { + Arrays.fill(r, (short)0); + return 1; + } + } + } + + return 0; + } + + /** + * Inversion of a polynomial in Zq[X]/(X^3 - zeta), used as + * a building block for inversion of elements in R_q in the NTT domain. + * This version is specifically for N=864 with 3-coefficient blocks. + * + * @param r Output polynomial array (3 elements) + * @param rPos Starting position in r array + * @param a Input polynomial array (3 elements) + * @param aPos Starting position in a array + * @param zeta Parameter defining X^3 - zeta + * @return 0 if a is invertible, 1 otherwise + */ + private int baseinv3(short[] r, int rPos, short[] a, int aPos, short zeta) + { + short a0 = a[aPos], a1 = a[aPos + 1], a2 = a[aPos + 2]; + + short r0 = montgomery_reduce(a1 * a2); + short r1 = montgomery_reduce(a2 * a2); + short r2 = montgomery_reduce(a1 * a1 - a0 * a2); + + r0 = montgomery_reduce(a0 * a0 - r0 * zeta); + r1 = montgomery_reduce(r1 * zeta - a0 * a1); + + short t = montgomery_reduce(r2 * a1 + r1 * a2); + t = montgomery_reduce(t * zeta + r0 * a0); + + if (t == 0) + { + return 1; // Not invertible + } + + t = fqinv(t); + t = montgomery_reduce(t * RINV); + + r[rPos] = montgomery_reduce(r0 * t); + r[rPos + 1] = montgomery_reduce(r1 * t); + r[rPos + 2] = montgomery_reduce(r2 * t); + + return 0; // Success + } + + /************************************************* + * Name: baseinv + * Description: Inversion of a polynomial in Zq[X]/(X^4 - zeta) + * Returns: 0 if a is invertible, 1 otherwise. + **************************************************/ + public int baseinv(short[] r, int rOff, short[] a, int aOff, short zeta) + { + short a0 = a[aOff], a1 = a[aOff + 1], a2 = a[aOff + 2], a3 = a[aOff + 3]; + short t0, t1, t2, t3; + + t0 = montgomery_reduce(a2 * a2 - 2 * a1 * a3); + t1 = montgomery_reduce(a3 * a3); + t0 = montgomery_reduce(a0 * a0 + t0 * zeta); + t1 = montgomery_reduce(a1 * a1 + t1 * zeta - 2 * a0 * a2); + t2 = montgomery_reduce(t1 * zeta); + + t3 = montgomery_reduce(t0 * t0 - t1 * t2); + + if (t3 == 0) + { + return 1; + } + + short r0 = montgomery_reduce(a0 * t0 + a2 * t2); + short r1 = montgomery_reduce(a3 * t2 + a1 * t0); + short r2 = montgomery_reduce(a2 * t0 + a0 * t1); + short r3 = montgomery_reduce(a1 * t1 + a3 * t0); + + t3 = fqinv(t3); + t3 = montgomery_reduce(t3 * RINV); + + r[rOff] = montgomery_reduce(r0 * t3); + r[rOff + 1] = (short)-montgomery_reduce(r1 * t3); + r[rOff + 2] = montgomery_reduce(r2 * t3); + r[rOff + 3] = (short)-montgomery_reduce(r3 * t3); + + return 0; + } + + public void shake256(byte[] output, int outOff, int outLen, byte[] input, int inLen) + { + shakeDigest.update(input, 0, inLen); + shakeDigest.doFinal(output, outOff, outLen); + } + + /** + * Computes the multiplicative inverse of a value in the finite field Z_q, + * using Montgomery arithmetic. + *

    + * The input is an ordinary field element x (no scaling), and the function + * returns x^{-1} scaled by R^2 modulo q, where R = 2^16 is the Montgomery radix. + * + * @param a The input value a = x mod q, as a signed 16-bit integer. + * @return A 16-bit integer congruent to x^{-1} * R^2 mod q. + */ + public short fqinv(short a) + { + short t1, t2, t3; + + // Follow the exact exponentiation sequence from the original C code + // This efficiently computes a^(q-2) mod q using a fixed addition chain. + t1 = fqmul(a, a); // a^2 + t2 = fqmul(t1, t1); // a^4 + t2 = fqmul(t2, t2); // a^8 + t3 = fqmul(t2, t2); // a^16 + + t1 = fqmul(t1, t2); // a^10 + + t2 = fqmul(t1, t3); // a^26 + t2 = fqmul(t2, t2); // a^52 + t2 = fqmul(t2, a); // a^53 + + t1 = fqmul(t1, t2); // a^63 + + t2 = fqmul(t2, t2); // a^106 + t2 = fqmul(t2, t2); // a^212 + t2 = fqmul(t2, t2); // a^424 + t2 = fqmul(t2, t2); // a^848 + t2 = fqmul(t2, t2); // a^1696 + t2 = fqmul(t2, t2); // a^3392 + t2 = fqmul(t2, t1); // a^3455 + + return t2; + } + + /** + * Multiplication of two polynomials in NTT domain. + * This merged function supports all three parameter sets: + * - N=768: 8-coefficient blocks, zeta offset 96 + * - N=864: 6-coefficient blocks, zeta offset 144 + * - N=1152: 8-coefficient blocks, zeta offset 144 + *

    + * All cases perform: r = a * b (in NTT domain) + * + * @param r Output polynomial + * @param a First input polynomial + * @param b Second input polynomial + */ + private void poly_basemul(short[] r, short[] a, short[] b) + { + for (int i = 0; i < n / doubleBlockSize; ++i) + { + basemul(r, doubleBlockSize * i, a, doubleBlockSize * i, b, doubleBlockSize * i, zetas[zetaOffset + i]); + basemul(r, doubleBlockSize * i + blockSize, a, doubleBlockSize * i + blockSize, b, doubleBlockSize * i + blockSize, (short)-zetas[zetaOffset + i]); + } + } + + + /** + * Serialization of a polynomial + * + * @param r Output byte array (must have space for NTRUPLUS_POLYBYTES bytes) + * @param a Input polynomial + */ + public void poly_tobytes(byte[] r, int rOff, short[] a) + { + int t0, t1; + + for (int i = 0, inOff = 0, outOff = rOff; i < halfN; i++) + { + t0 = a[inOff++]; + t0 += (t0 >> 15) & Q; + + t1 = a[inOff++]; + t1 += (t1 >> 15) & Q; + + // Pack two 13-bit coefficients into three bytes + r[outOff++] = (byte)(t0); // Lower 8 bits of first coefficient + r[outOff++] = (byte)((t0 >> 8) | (t1 << 4)); // Upper 5 bits of t0, lower 4 bits of t1 + r[outOff++] = (byte)(t1 >> 4); // Upper 8 bits of t1 + } + } + + /** + * Deterministically generates a secret polynomial g and its + * multiplicative inverse ginv in the NTT domain. + * + * @param g Output polynomial g (in NTT domain) + * @param ginv Output multiplicative inverse of g in the NTT domain + * @param coins 32-byte deterministic seed + * @return 0 on success; non-zero if g is not invertible in the NTT domain + */ + public int geng_derand(short[] g, short[] ginv, byte[] coins) + { + byte[] buf = new byte[quarterN]; + shake256(buf, 0, buf.length, coins, 32); + poly_cbd1(g, buf, 0); + poly_triple(g, g); + poly_ntt(g); + return poly_baseinv(ginv, g); + } + + /** + * Computes the deterministic public and secret key pair from + * the secret polynomials f and g and their multiplicative + * inverses finv and ginv in the NTT domain. + * + * @param pk Output public key (must have length params.getPublicKeyBytes()) + * @param sk Output secret key (must have length params.getSecretKeyBytes()) + * @param f Secret polynomial f (in NTT domain) + * @param finv Multiplicative inverse of f (in NTT domain) + * @param g Secret polynomial g (in NTT domain) + * @param ginv Multiplicative inverse of g (in NTT domain) + */ + public void crypto_kem_keypair_derand(byte[] pk, byte[] sk, short[] f, short[] finv, short[] g, short[] ginv) + { + short[] h = new short[n]; + short[] hinv = new short[n]; + + // Compute h = g * finv (in NTT domain) + poly_basemul(h, g, finv); + + // Compute hinv = f * ginv (in NTT domain) + poly_basemul(hinv, f, ginv); + + // Serialize h to get the public key + poly_tobytes(pk, 0, h); + + // Serialize f to the first part of the secret key + poly_tobytes(sk, 0, f); + + // Serialize hinv to the second part of the secret key (offset by NTRUPLUS_POLYBYTES) + poly_tobytes(sk, polyBytes, hinv); + + // Compute hash of public key and store in the third part of secret key + shake256(sk, polyBytes << 1, 32, hash_f_domain, pk, 0, polyBytes); + } + + /** + * SOTP encoding + */ + private void poly_sotp_encode(short[] r, byte[] msg, byte[] buf) + { + Bytes.xorTo(eighthN, msg, buf); + poly_cbd1(r, buf, 0); + } + + /** + * Deserialization of a polynomial from bytes + */ + private void poly_frombytes(short[] r, byte[] a, int aPos) + { + for (int i = 0, inOff = aPos, outOff = 0; i < halfN; i++, inOff += 3) + { + r[outOff++] = (short)(((a[inOff] & 0xFF) | ((a[inOff + 1] & 0xFF) << 8)) & 0xFFF); + r[outOff++] = (short)(((a[inOff + 1] & 0xFF) >> 4 | ((a[inOff + 2] & 0xFF) << 4)) & 0xFFF); + } + } + + /** + * Multiplication then addition of three polynomials in NTT domain. + * This merged function supports all three parameter sets: + * - N=768: 8-coefficient blocks, zeta offset 96 + * - N=864: 6-coefficient blocks, zeta offset 144 + * - N=1152: 8-coefficient blocks, zeta offset 144 + *

    + * All cases perform: r = a * b + c (in NTT domain) + * + * @param r Output polynomial + * @param a First input polynomial + * @param b Second input polynomial + * @param c Third input polynomial to add + */ + private void poly_basemul_add(short[] r, short[] a, short[] b, short[] c) + { + for (int i = 0, pos = 0, zetaOff = zetaOffset; i < n / doubleBlockSize; ++i, zetaOff++) + { + basemul_add(r, pos, a, pos, b, pos, c, pos, zetas[zetaOff], blockSize); + pos += blockSize; + basemul_add(r, pos, a, pos, b, pos, c, pos, (short)-zetas[zetaOff], blockSize); + pos += blockSize; + } + } + + /** + * Multiplication then addition of polynomials in Zq[X]/(X^d - zeta), + * used for multiplication of elements in R_q in the NTT domain. + *

    + * Supports: + * - 4-coefficient blocks (d=4) for N=768, 1152 + * - 3-coefficient blocks (d=3) for N=864 + */ + private void basemul_add(short[] r, int rPos, short[] a, int aPos, + short[] b, int bPos, short[] c, int cPos, + short zeta, int blockSize) + { + // Common multiplication core + multiplyCore(r, rPos, a, aPos, b, bPos, zeta, blockSize); + + // Addition and final scaling + finalizeWithAddition(r, rPos, c, cPos, blockSize); + } + + /** + * Multiplication of polynomials in Zq[X]/(X^d - zeta) + */ + private void basemul(short[] r, int rPos, short[] a, int aPos, + short[] b, int bPos, short zeta) + { + // Common multiplication core + multiplyCore(r, rPos, a, aPos, b, bPos, zeta, blockSize); + + // Final scaling (multiplication only) + finalizeMultiplication(r, rPos, blockSize); + } + + /** + * Core multiplication logic shared by both basemul and basemul_add + */ + private void multiplyCore(short[] r, int rPos, short[] a, int aPos, + short[] b, int bPos, short zeta, int blockSize) + { + // Extract common coefficients (a0, a1, a2, b0, b1, b2) + short a0 = a[aPos], a1 = a[aPos + 1], a2 = a[aPos + 2]; + short b0 = b[bPos], b1 = b[bPos + 1], b2 = b[bPos + 2]; + int temp; + + if (blockSize == 4) + { + // 4-coefficient specific logic + short a3 = a[aPos + 3]; + short b3 = b[bPos + 3]; + + // High-degree terms + temp = (int)a1 * b3 + (int)a2 * b2 + (int)a3 * b1; + r[rPos] = montgomery_reduce(temp); + + temp = (int)a2 * b3 + (int)a3 * b2; + r[rPos + 1] = montgomery_reduce(temp); + + temp = (int)a3 * b3; + temp = montgomery_reduce(temp); + + // Apply zeta to middle terms + temp = temp * zeta + (int)a0 * b2 + (int)a1 * b1 + (int)a2 * b0; + r[rPos + 2] = montgomery_reduce(temp); + + // Compute r3 term + temp = (int)a0 * b3 + (int)a1 * b2 + (int)a2 * b1 + (int)a3 * b0; + r[rPos + 3] = montgomery_reduce(temp); + } + else + { + // 3-coefficient specific logic + // High-degree terms + temp = (int)a2 * b1 + (int)a1 * b2; + r[rPos] = montgomery_reduce(temp); + + temp = (int)a2 * b2; + r[rPos + 1] = montgomery_reduce(temp); + + // Compute r2 term + temp = (int)a2 * b0 + (int)a1 * b1 + (int)a0 * b2; + r[rPos + 2] = montgomery_reduce(temp); + } + + // Common low-degree terms (apply zeta to r0 and r1) + temp = (int)r[rPos] * zeta + (int)a0 * b0; + r[rPos] = montgomery_reduce(temp); + + temp = (int)r[rPos + 1] * zeta + (int)a0 * b1 + (int)a1 * b0; + r[rPos + 1] = montgomery_reduce(temp); + } + + /** + * Final scaling for multiplication with addition (basemul_add) + */ + private void finalizeWithAddition(short[] r, int rPos, short[] c, int cPos, int blockSize) + { + int rValue = 1 << 16; // NTRUPLUS_R = 2^16 = 65536 + + // Handle all coefficients + for (int i = 0; i < blockSize; i++) + { + int temp = c[cPos++] * rValue + (int)r[rPos] * RSQ; + r[rPos++] = montgomery_reduce(temp); + } + } + + /** + * Final scaling for multiplication only (basemul) + */ + private void finalizeMultiplication(short[] r, int rPos, int blockSize) + { + for (int i = 0; i < blockSize; i++) + { + r[rPos] = montgomery_reduce((int)r[rPos++] * RSQ); + } + } + + /** + * Deterministic KEM encapsulation + */ + public void crypto_kem_enc_derand(byte[] ct, int ctPos, byte[] ss, int ssPos, + byte[] pk, int pkPos, byte[] coins, int coinsPos) + { + byte[] msg = new byte[eighthN + SSBytes]; + byte[] buf1 = new byte[SSBytes + quarterN]; + byte[] buf2 = new byte[polyBytes]; + + short[] c = new short[n]; + short[] h = new short[n]; + short[] r = new short[n]; + short[] m = new short[n]; + + // Copy first n/8 bytes of coins to msg + System.arraycopy(coins, coinsPos, msg, 0, eighthN); + + // Compute hash_f of pk and store in remaining part of msg + shake256(msg, eighthN, 32, hash_f_domain, pk, pkPos, polyBytes); + + // Compute hash_h of msg, result in buf1 + shake256(buf1, 0, buf1.length, hash_h_domain, msg, 0, msg.length); + // Generate r from second part of buf1 + poly_cbd1(r, buf1, SSBytes); + poly_ntt(r); + + // Convert r to bytes and then hash_g + poly_tobytes(buf2, 0, r); + shake256(buf2, 0, quarterN, hash_g_domain, buf2, 0, polyBytes); + + // Generate m by encoding msg and buf2 + poly_sotp_encode(m, msg, buf2); + poly_ntt(m); + + // Convert pk to polynomial h + poly_frombytes(h, pk, pkPos); + + // Compute c = h*r + m in NTT domain + poly_basemul_add(c, h, r, m); + + // Convert c to ciphertext + poly_tobytes(ct, ctPos, c); + + // Copy first ssBytes of buf1 to ss + System.arraycopy(buf1, 0, ss, ssPos, SSBytes); + } + + /** + * Updated SHAKE256 with offsets + */ + private void shake256(byte[] output, int outOff, int outLen, byte domainSeperation, byte[] input, int inOff, int inLen) + { + shakeDigest.update(domainSeperation); + shakeDigest.update(input, inOff, inLen); + shakeDigest.doFinal(output, outOff, outLen); + } + + /** + * Inverse number-theoretic transform (NTT) in R_q. + * Transforms the NTT representation back to the coefficient representation in R_q. + *

    + * Supports: + * - N=768: 4-coefficient blocks, step 4-64, 384-block processing + * - N=864: 3-coefficient blocks, step 3-24, multiplication by 3 in second loop + * - N=1152: 4-coefficient blocks, step 4-32, multiplication by 3 in second loop + * + * @param r Output vector (coefficient representation) + */ + private void poly_invntt(short[] r) + { + short t1, t2, t3; + short zeta1, zeta2; + short a1, a2; + int k; + if (n == 768) + { + a1 = (short)-811; + a2 = (short)-1622; + k = 191; + } + else + { + a1 = (short)-1693; + a2 = (short)71; + k = 287; + } + + int minStep = params.getMinStep(); + int baseStep = params.getBaseStep(); + for (; minStep <= baseStep; minStep <<= 1) + { + for (int start = 0; start < n; start += (minStep << 1)) + { + zeta1 = zetas[k--]; + for (int i = start, pos = start + minStep; i < start + minStep; i++, pos++) + { + t1 = r[pos]; + r[pos] = fqmul(zeta1, (short)(t1 - r[i])); + r[i] = barrett_reduce((short)(r[i] + t1)); + } + } + } + for (int step = baseStep << 1; step <= n / 6; step *= 3) + { + int twoStep = step << 1; + for (int start = 0; start < n; start += 3 * step) + { + zeta2 = zetas[k--]; + zeta1 = zetas[k--]; + + for (int i = start, pos1 = start + step, pos2 = start + twoStep; i < start + step; i++, pos1++, pos2++) + { + t1 = fqmul(OMEGA, (short)(r[pos1] - r[i])); + t2 = fqmul(zeta1, (short)(r[pos2] - r[i] + t1)); + t3 = fqmul(zeta2, (short)(r[pos2] - r[pos1] - t1)); + + r[i] = barrett_reduce((short)(r[i] + r[pos1] + r[pos2])); + r[pos1] = t2; + r[pos2] = t3; + } + } + } + + for (int i = 0; i < halfN; i++) + { + t1 = (short)(r[i] + r[i + halfN]); + t2 = fqmul((short)-1665, (short)(r[i] - r[i + halfN])); + r[i] = fqmul(a1, (short)(t1 - t2)); + r[i + halfN] = fqmul(a2, t2); + } + } + + /** + * Compute modulus 3 operation to polynomial + */ + private void poly_crepmod3(short[] r, short[] a) + { + for (int i = 0; i < n; i++) + { + r[i] = crepmod3(a[i]); + } + } + + /** + * Compute modulus 3 operation + */ + private short crepmod3(short a) + { + short t; + final short v = (short)(((1 << 15) + 1) / 3); + + // Reduce a to range [0, q-1] + // Center around 0: subtract (q+1)/2 + a += (short)(((a >> 15) & Q) - QPlus1_Half); + // If negative, add q back + // Subtract (q-1)/2 to get centered around 0 + a += (short)(((a >> 15) & Q) - QMinus1_Half); + + // Barrett reduction for mod 3 + t = (short)((v * a + (1 << 14)) >> 15); + t *= 3; + return (short)(a - t); + } + + /** + * Subtract two polynomials; no modular reduction is performed + */ + private void poly_sub(short[] r, short[] a, short[] b) + { + for (int i = 0; i < n; ++i) + { + r[i] = (short)(a[i] - b[i]); + } + } + + /** + * Decode a message using SOTP_INV and a random + */ + private int poly_sotp_decode(byte[] msg, short[] a, byte[] buf) + { + int r = 0; + byte mask; + + for (int i = 0; i < eighthN; i++) + { + int t1 = buf[i] & 0xFF; // Convert to unsigned + int t2 = buf[i + eighthN] & 0xFF; + byte t3 = 0; + + for (int j = 0; j < 8; j++) + { + int t4 = t2 & 0x1; + t4 += a[8 * i + j]; + r |= t4; + t4 = (t4 ^ t1) & 0x1; + t3 ^= (byte)(t4 << j); + + t1 >>= 1; + t2 >>= 1; + } + + msg[i] = t3; + } + + r = r >> 1; + r = (-r) >> 31; // This is the C trick: -(uint32_t)r) >> 31 + + mask = (byte)(r - 1); + + for (int i = 0; i < eighthN; i++) + { + msg[i] &= mask; + } + + return r; + } + + /** + * Compares two byte arrays for equality in constant time + */ + private int verify(byte[] a, byte[] b, int len) + { + int acc = 0; + + for (int i = 0; i < len; i++) + { + acc |= (a[i] ^ b[i]) & 0xFF; + } + + // Return 0 if equal, 1 otherwise + // Equivalent to: (-(uint64_t)acc) >> 63 + return (acc != 0) ? 1 : 0; + } + + /** + * Performs NTRU+ KEM decapsulation + */ + public void crypto_kem_dec(byte[] ss, int ssPos, byte[] ct, int ctPos, byte[] sk, int skPos) + { + byte[] msg = new byte[eighthN + SSBytes]; + byte[] buf1 = new byte[polyBytes]; + byte[] buf2 = new byte[polyBytes]; + byte[] buf3 = new byte[polyBytes + SSBytes]; + + int fail; + + short[] c = new short[n]; + short[] f = new short[n]; + short[] hinv = new short[n]; + short[] r1 = new short[n]; + short[] r2 = new short[n]; + short[] m1 = new short[n]; + short[] m2 = new short[n]; + + // Load ciphertext and secret key components + poly_frombytes(c, ct, ctPos); + poly_frombytes(f, sk, skPos); + poly_frombytes(hinv, sk, skPos + polyBytes); + + // m1 = c * f + poly_basemul(m1, c, f); + poly_invntt(m1); // Convert from NTT domain + poly_crepmod3(m1, m1); // Reduce mod 3 + + // m2 = NTT(m1) + System.arraycopy(m1, 0, m2, 0, n); + poly_ntt(m2); + + // c = c - m2 + poly_sub(c, c, m2); + + // r2 = c * hinv + poly_basemul(r2, c, hinv); + + // Convert r2 to bytes and hash + poly_tobytes(buf1, 0, r2); + shake256(buf2, 0, quarterN, hash_g_domain, buf1, 0, polyBytes); + + // Decode message + fail = poly_sotp_decode(msg, m1, buf2); + + // Append hash of pk from secret key + System.arraycopy(sk, skPos + 2 * polyBytes, msg, eighthN, SSBytes); + + // Hash H + shake256(buf3, 0, buf3.length, hash_h_domain, msg, 0, msg.length); + + // Generate r1 from second part of buf3 + poly_cbd1(r1, buf3, SSBytes); + poly_ntt(r1); + poly_tobytes(buf2, 0, r1); + + // Verify that buf1 (from r2) equals buf2 (from r1) + fail |= verify(buf1, buf2, polyBytes); + + // Copy shared secret, zeroing on failure + if (fail != 0) + { + Arrays.fill(ss, (byte)0); + } + else + { + System.arraycopy(buf3, 0, ss, ssPos, SSBytes); + } + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKEMExtractor.java new file mode 100644 index 0000000000..fb8ff1971f --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKEMExtractor.java @@ -0,0 +1,35 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import org.bouncycastle.crypto.EncapsulatedSecretExtractor; + +public class NTRUPlusKEMExtractor + implements EncapsulatedSecretExtractor +{ + private final NTRUPlusPrivateKeyParameters privateKey; + private final NTRUPlusEngine engine; + + public NTRUPlusKEMExtractor(NTRUPlusPrivateKeyParameters privateKey) + { + if (privateKey == null) + { + throw new NullPointerException("'privateKey' cannot be null"); + } + + this.privateKey = privateKey; + this.engine = new NTRUPlusEngine(privateKey.getParameters()); + } + + @Override + public byte[] extractSecret(byte[] encapsulation) + { + byte[] ss = new byte[NTRUPlusEngine.SSBytes]; + engine.crypto_kem_dec(ss, 0, encapsulation, 0, privateKey.getEncoded(), 0); + return ss; + } + + @Override + public int getEncapsulationLength() + { + return privateKey.getParameters().getCiphertextBytes(); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKEMGenerator.java new file mode 100644 index 0000000000..2b4a9b0ce4 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKEMGenerator.java @@ -0,0 +1,33 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.EncapsulatedSecretGenerator; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.crypto.util.SecretWithEncapsulationImpl; + +public class NTRUPlusKEMGenerator + implements EncapsulatedSecretGenerator +{ + private final SecureRandom sr; + + public NTRUPlusKEMGenerator(SecureRandom random) + { + this.sr = random; + } + + @Override + public SecretWithEncapsulation generateEncapsulated(AsymmetricKeyParameter recipientKey) + { + NTRUPlusPublicKeyParameters key = (NTRUPlusPublicKeyParameters)recipientKey; + NTRUPlusParameters params = key.getParameters(); + byte[] ct = new byte[params.getCiphertextBytes()]; + byte[] ss = new byte[NTRUPlusEngine.SSBytes]; + NTRUPlusEngine engine = new NTRUPlusEngine(params); + byte[] coins = new byte[params.getN() >> 3]; + sr.nextBytes(coins); + engine.crypto_kem_enc_derand(ct, 0, ss,0, key.getEncoded(), 0, coins, 0); + return new SecretWithEncapsulationImpl(ss, ct); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyGenerationParameters.java new file mode 100644 index 0000000000..2fdaf28694 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyGenerationParameters.java @@ -0,0 +1,24 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.KeyGenerationParameters; + +public class NTRUPlusKeyGenerationParameters + extends KeyGenerationParameters +{ + private final NTRUPlusParameters params; + + public NTRUPlusKeyGenerationParameters( + SecureRandom random, + NTRUPlusParameters mayoParameters) + { + super(random, 256); + this.params = mayoParameters; + } + + public NTRUPlusParameters getParameters() + { + return params; + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyPairGenerator.java new file mode 100644 index 0000000000..3ff44c27b1 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyPairGenerator.java @@ -0,0 +1,81 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.bouncycastle.crypto.KeyGenerationParameters; + +/** + * Implementation of the NTRU+ asymmetric key pair generator following the NTRU+ KEM specifications. + *

    + * This generator produces {@link NTRUPlusPublicKeyParameters} and {@link NTRUPlusPrivateKeyParameters} + * based on the chosen NTRU+ algorithm parameters. The implementation follows the specification + * defined in the official NTRU+ documentation and reference implementation. + *

    + *

    + * NTRU+ is a key encapsulation mechanism (KEM) and public key encryption (PKE) scheme based on + * structured lattices. It was selected as a final algorithm in the Korean Post-Quantum Cryptography + * Competition (KpqC). + *

    + * + *

    References:

    + * + */ +public class NTRUPlusKeyPairGenerator + implements AsymmetricCipherKeyPairGenerator +{ + private NTRUPlusParameters params; + private SecureRandom random; + + @Override + public void init(KeyGenerationParameters param) + { + this.params = ((NTRUPlusKeyGenerationParameters)param).getParameters(); + this.random = param.getRandom(); + } + + @Override + public AsymmetricCipherKeyPair generateKeyPair() + { + byte[] pk = new byte[params.getPublicKeyBytes()]; + byte[] sk = new byte[params.getSecretKeyBytes()]; + NTRUPlusEngine engine = new NTRUPlusEngine(params); + byte[] coins = new byte[NTRUPlusEngine.SSBytes]; // NTRUPLUS_SYMBYTES + + int n = params.getN(); + // Create polynomial objects + short[] f = new short[n]; + short[] finv = new short[n]; + short[] g = new short[n]; + short[] ginv = new short[n]; + + // Generate f and finv (retry if f is not invertible) + boolean fInvertible; + do + { + // Generate random bytes for the seed + random.nextBytes(coins); + fInvertible = (engine.genf_derand(f, finv, coins) == 0); + } + while (!fInvertible); + + // Generate g and ginv (retry if g is not invertible) + boolean gInvertible; + do + { + // Generate new random bytes for the seed + random.nextBytes(coins); + gInvertible = (engine.geng_derand(g, ginv, coins) == 0); + } + while (!gInvertible); + + // Generate the actual key pair using the derived polynomials + engine.crypto_kem_keypair_derand(pk, sk, f, finv, g, ginv); + return new AsymmetricCipherKeyPair(new NTRUPlusPublicKeyParameters(params, pk), new NTRUPlusPrivateKeyParameters(params, sk)); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyParameters.java new file mode 100644 index 0000000000..2bb2dec810 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusKeyParameters.java @@ -0,0 +1,23 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; + +public class NTRUPlusKeyParameters + extends AsymmetricKeyParameter +{ + private final NTRUPlusParameters params; + + public NTRUPlusKeyParameters( + boolean isPrivate, + NTRUPlusParameters params) + { + super(isPrivate); + this.params = params; + } + + public NTRUPlusParameters getParameters() + { + return params; + } +} + diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusParameters.java new file mode 100644 index 0000000000..6ebdc14c03 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusParameters.java @@ -0,0 +1,175 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +public class NTRUPlusParameters +{ + private static final short[] zetas768 = new short[]{ + -147, -1033, -682, -248, -708, 682, 1, -722, + -723, -257, -1124, -867, -256, 1484, 1262, -1590, + 1611, 222, 1164, -1346, 1716, -1521, -357, 395, + -455, 639, 502, 655, -699, 541, 95, -1577, + -1241, 550, -44, 39, -820, -216, -121, -757, + -348, 937, 893, 387, -603, 1713, -1105, 1058, + 1449, 837, 901, 1637, -569, -1617, -1530, 1199, + 50, -830, -625, 4, 176, -156, 1257, -1507, + -380, -606, 1293, 661, 1428, -1580, -565, -992, + 548, -800, 64, -371, 961, 641, 87, 630, + 675, -834, 205, 54, -1081, 1351, 1413, -1331, + -1673, -1267, -1558, 281, -1464, -588, 1015, 436, + 223, 1138, -1059, -397, -183, 1655, 559, -1674, + 277, 933, 1723, 437, -1514, 242, 1640, 432, + -1583, 696, 774, 1671, 927, 514, 512, 489, + 297, 601, 1473, 1130, 1322, 871, 760, 1212, + -312, -352, 443, 943, 8, 1250, -100, 1660, + -31, 1206, -1341, -1247, 444, 235, 1364, -1209, + 361, 230, 673, 582, 1409, 1501, 1401, 251, + 1022, -1063, 1053, 1188, 417, -1391, -27, -1626, + 1685, -315, 1408, -1248, 400, 274, -1543, 32, + -1550, 1531, -1367, -124, 1458, 1379, -940, -1681, + 22, 1709, -275, 1108, 354, -1728, -968, 858, + 1221, -218, 294, -732, -1095, 892, 1588, -779 + }; + + private static final short[] zetas864_1152 = new short[]{ + -147, -1033, -1265, 708, 460, 1265, -467, 727, + 556, 1307, -773, -161, 1200, -1612, 570, 1529, + 1135, -556, 1120, 298, -822, -1556, -93, 1463, + 532, -377, -909, 58, -392, -450, 1722, 1236, + -486, -491, -1569, -1078, 36, 1289, -1443, 1628, + 1664, -725, -952, 99, -1020, 353, -599, 1119, + 592, 839, 1622, 652, 1244, -783, -1085, -726, + 566, -284, -1369, -1292, 268, -391, 781, -172, + 96, -1172, 211, 737, 473, -445, -234, 264, + -1536, 1467, -676, -1542, -170, 635, -705, -1332, + -658, 831, -1712, 1311, 1488, -881, 1087, -1315, + 1245, -75, 791, -6, -875, -697, -70, -1162, + 287, -767, -945, 1598, -882, 1261, 206, 654, + -1421, -81, 716, -1251, 838, -1300, 1035, -104, + 966, -558, -61, -1704, 404, -899, 862, -1593, + -1460, -37, 1266, 965, -1584, -1404, -265, -942, + 905, 1195, -619, 787, 118, 576, 286, -1475, + -194, 928, 1229, -1032, 1608, 1111, -1669, 642, + -1323, 163, 309, 981, -557, -258, 232, -1680, + -1657, -1233, 144, 1699, 311, -1060, 578, 1298, + -403, 1607, 1074, -148, 447, -1568, 1142, -402, + -1412, -623, 855, 365, -98, -244, 407, 1225, + 416, 683, -105, 1714, -1019, 1061, 1163, 638, + 798, 1493, -351, 396, -542, -9, 1616, -139, + -987, -482, 889, 238, -1513, 466, -1089, -101, + 849, -426, 1589, 1487, 671, 1459, -776, 255, + -1014, 1144, 472, -1153, -325, 1519, -26, -1123, + 324, 1230, 1547, -593, -428, 1192, 1072, -1564, + 688, -333, 1023, -1686, 841, 824, -71, 1587, + 522, -323, 1148, 389, 1231, 384, 1343, 169, + 628, -1329, -1056, -936, 24, -293, 1523, -300, + -1654, 891, -962, -67, 179, -1177, 844, -509, + -1677, -1565, -549, -1508, 1191, -280, -43, 669, + -746, 753, 770, -1046, 1711, 1438, 690, 1083, + 1062, 1727, -883, 553, 1670, 66, 825, -133, + -1586, 637, -680, -917, 644, -372, -1193, -1136 + }; + + // Parameter sets for different security levels + public static final NTRUPlusParameters ntruplus_kem_768 = new NTRUPlusParameters( + "NTRU+KEM768", // name + 768, // NTRUPLUS_N + 1152, // NTRUPLUS_PUBLICKEYBYTES + 4, + 64, + 96, + zetas768 + ); + + public static final NTRUPlusParameters ntruplus_kem_864 = new NTRUPlusParameters( + "NTRU+KEM864", // name + 864, // NTRUPLUS_N + 1296, // NTRUPLUS_PUBLICKEYBYTES + 3, + 24, + 144, + zetas864_1152 + ); + + public static final NTRUPlusParameters ntruplus_kem_1152 = new NTRUPlusParameters( + "NTRU+KEM1152", // name + 1152, // NTRUPLUS_N + 1728, // NTRUPLUS_PUBLICKEYBYTES + 4, + 32, + 144, + zetas864_1152 + ); + + // Instance fields + private final String name; + private final int n; // NTRUPLUS_N + private final int publicKeyBytes; // NTRUPLUS_PUBLICKEYBYTES + private final int secretKeyBytes; // NTRUPLUS_SECRETKEYBYTES + private final int minStep; + private final int baseStep; + private final int zetasOffset; + private final short[] zetas; + + + private NTRUPlusParameters(String name, int n, int publicKeyBytes, int minStep, int baseStep, int zetasOffset, short[] zetas) + { + this.name = name; + this.n = n; + this.publicKeyBytes = publicKeyBytes; + this.secretKeyBytes = (publicKeyBytes << 1) + 32; + this.minStep = minStep; + this.baseStep = baseStep; + this.zetasOffset = zetasOffset; + this.zetas = zetas; + } + + // Getters for all parameters + public String getName() + { + return name; + } + + public int getN() + { + return n; + } + + public int getSsBytes() + { + return 32; + } + + public int getPublicKeyBytes() + { + return publicKeyBytes; + } + + public int getSecretKeyBytes() + { + return secretKeyBytes; + } + + public int getCiphertextBytes() + { + return publicKeyBytes; + } + + public short[] getZetas() + { + return zetas; + } + + int getBaseStep() + { + return baseStep; + } + + int getMinStep() + { + return minStep; + } + + int getZetasOffset() + { + return zetasOffset; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusPrivateKeyParameters.java new file mode 100644 index 0000000000..fa2b3c0716 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusPrivateKeyParameters.java @@ -0,0 +1,20 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import org.bouncycastle.util.Arrays; + +public class NTRUPlusPrivateKeyParameters + extends NTRUPlusKeyParameters +{ + private final byte[] sk; + + public NTRUPlusPrivateKeyParameters(NTRUPlusParameters params, byte[] sk) + { + super(true, params); + this.sk = Arrays.clone(sk); + } + + public byte[] getEncoded() + { + return Arrays.clone(sk); + } +} diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusPublicKeyParameters.java new file mode 100644 index 0000000000..4fdfab9907 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruplus/NTRUPlusPublicKeyParameters.java @@ -0,0 +1,20 @@ +package org.bouncycastle.pqc.crypto.ntruplus; + +import org.bouncycastle.util.Arrays; + +public class NTRUPlusPublicKeyParameters + extends NTRUPlusKeyParameters +{ + private final byte[] p; + + public NTRUPlusPublicKeyParameters(NTRUPlusParameters params, byte[] p) + { + super(false, params); + this.p = Arrays.clone(p); + } + + public byte[] getEncoded() + { + return Arrays.clone(p); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMExtractor.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMExtractor.java index 319c4e65b2..7d82576c48 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMExtractor.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMExtractor.java @@ -10,6 +10,11 @@ public class SNTRUPrimeKEMExtractor public SNTRUPrimeKEMExtractor(SNTRUPrimePrivateKeyParameters privateKey) { + if (privateKey == null) + { + throw new NullPointerException("'privateKey' cannot be null"); + } + this.privateKey = privateKey; } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMGenerator.java b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMGenerator.java index 9f1923260e..ba97f204f0 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMGenerator.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/ntruprime/SNTRUPrimeKEMGenerator.java @@ -2,6 +2,7 @@ import java.security.SecureRandom; +import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.EncapsulatedSecretGenerator; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; @@ -15,7 +16,7 @@ public class SNTRUPrimeKEMGenerator public SNTRUPrimeKEMGenerator(SecureRandom random) { - this.random = random; + this.random = CryptoServicesRegistrar.getSecureRandom(random); } @Override diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java index 9031b19048..b009f1b66e 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java @@ -53,6 +53,8 @@ import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; @@ -498,6 +500,12 @@ else if (algOID.on(BCObjectIdentifiers.snova)) SnovaParameters snovaParams = Utils.snovaParamsLookup(algOID); return new SnovaPrivateKeyParameters(snovaParams, keyEnc); } + else if (algOID.on(BCObjectIdentifiers.ntruPlus)) + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(); + NTRUPlusParameters ntruPlusParams = Utils.ntruPlusParamsLookup(algOID); + return new NTRUPlusPrivateKeyParameters(ntruPlusParams, keyEnc); + } else { throw new RuntimeException("algorithm identifier in private key not recognised"); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java index c3b7575cf2..101e127081 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java @@ -37,6 +37,7 @@ import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePrivateKeyParameters; import org.bouncycastle.pqc.crypto.picnic.PicnicPrivateKeyParameters; @@ -333,6 +334,13 @@ else if (privateKey instanceof SnovaPrivateKeyParameters) byte[] encoding = params.getEncoded(); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); } + else if (privateKey instanceof NTRUPlusPrivateKeyParameters) + { + NTRUPlusPrivateKeyParameters params = (NTRUPlusPrivateKeyParameters)privateKey; + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntruPlusOidLookup(params.getParameters())); + byte[] encoding = params.getEncoded(); + return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); + } else { throw new IOException("key parameters not recognized"); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java index 256ed74991..bbdbfd2cb1 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java @@ -47,6 +47,8 @@ import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; @@ -302,6 +304,10 @@ public class PublicKeyFactory converters.put(BCObjectIdentifiers.snova_75_33_2_ssk, new SnovaConverter()); converters.put(BCObjectIdentifiers.snova_75_33_2_shake_esk, new SnovaConverter()); converters.put(BCObjectIdentifiers.snova_75_33_2_shake_ssk, new SnovaConverter()); + + converters.put(BCObjectIdentifiers.ntruPlus768, new NTRUPlusConverter()); + converters.put(BCObjectIdentifiers.ntruPlus864, new NTRUPlusConverter()); + converters.put(BCObjectIdentifiers.ntruPlus1152, new NTRUPlusConverter()); } /** @@ -892,4 +898,18 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje return new SnovaPublicKeyParameters(snovaParams, keyEnc); } } + + private static class NTRUPlusConverter + extends SubjectPublicKeyInfoConverter + { + AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + throws IOException + { + byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); + + NTRUPlusParameters ntruPlusParams = Utils.ntruPlusParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + + return new NTRUPlusPublicKeyParameters(ntruPlusParams, keyEnc); + } + } } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java index f8c7b20099..88ff88981b 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java @@ -29,6 +29,7 @@ import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; import org.bouncycastle.pqc.crypto.newhope.NHPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPublicKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePublicKeyParameters; import org.bouncycastle.pqc.crypto.picnic.PicnicPublicKeyParameters; @@ -300,6 +301,13 @@ else if (publicKey instanceof SnovaPublicKeyParameters) AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.snovaOidLookup(params.getParameters())); return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); } + else if (publicKey instanceof NTRUPlusPublicKeyParameters) + { + NTRUPlusPublicKeyParameters params = (NTRUPlusPublicKeyParameters)publicKey; + byte[] encoding = params.getEncoded(); + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntruPlusOidLookup(params.getParameters())); + return new SubjectPublicKeyInfo(algorithmIdentifier, new DEROctetString(encoding)); + } else { throw new IOException("key parameters not recognized"); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java index 8fdcd5ac6d..9e78a36277 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/Utils.java @@ -30,6 +30,7 @@ import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters; import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; import org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; import org.bouncycastle.pqc.crypto.picnic.PicnicParameters; @@ -50,7 +51,7 @@ class Utils static final AlgorithmIdentifier XMSS_SHA512 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512); static final AlgorithmIdentifier XMSS_SHAKE128 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake128); static final AlgorithmIdentifier XMSS_SHAKE256 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256); - + static final Map picnicOids = new HashMap(); static final Map picnicParams = new HashMap(); @@ -108,6 +109,9 @@ class Utils static final Map snovaOids = new HashMap(); static final Map snovaParams = new HashMap(); + static final Map ntruPlusOids = new HashMap(); + static final Map ntruPlusParams = new HashMap(); + static { mcElieceOids.put(CMCEParameters.mceliece348864r3, BCObjectIdentifiers.mceliece348864_r3); @@ -571,6 +575,14 @@ class Utils snovaParams.put(BCObjectIdentifiers.snova_75_33_2_esk, SnovaParameters.SNOVA_75_33_2_ESK); snovaParams.put(BCObjectIdentifiers.snova_75_33_2_shake_ssk, SnovaParameters.SNOVA_75_33_2_SHAKE_SSK); snovaParams.put(BCObjectIdentifiers.snova_75_33_2_shake_esk, SnovaParameters.SNOVA_75_33_2_SHAKE_ESK); + + ntruPlusParams.put(BCObjectIdentifiers.ntruPlus768, NTRUPlusParameters.ntruplus_kem_768); + ntruPlusParams.put(BCObjectIdentifiers.ntruPlus864, NTRUPlusParameters.ntruplus_kem_864); + ntruPlusParams.put(BCObjectIdentifiers.ntruPlus1152, NTRUPlusParameters.ntruplus_kem_1152); + + ntruPlusOids.put(NTRUPlusParameters.ntruplus_kem_768, BCObjectIdentifiers.ntruPlus768); + ntruPlusOids.put(NTRUPlusParameters.ntruplus_kem_864, BCObjectIdentifiers.ntruPlus864); + ntruPlusOids.put(NTRUPlusParameters.ntruplus_kem_1152, BCObjectIdentifiers.ntruPlus1152); } static ASN1ObjectIdentifier slhdsaOidLookup(SLHDSAParameters params) @@ -885,6 +897,16 @@ static SnovaParameters snovaParamsLookup(ASN1ObjectIdentifier oid) return (SnovaParameters)snovaParams.get(oid); } + static NTRUPlusParameters ntruPlusParamsLookup(ASN1ObjectIdentifier oid) + { + return (NTRUPlusParameters)ntruPlusParams.get(oid); + } + + static ASN1ObjectIdentifier ntruPlusOidLookup(NTRUPlusParameters params) + { + return (ASN1ObjectIdentifier)ntruPlusOids.get(params); + } + private static boolean isRaw(byte[] data) { // check well-formed first diff --git a/core/src/main/java/org/bouncycastle/util/Pack.java b/core/src/main/java/org/bouncycastle/util/Pack.java index b0a6646e02..486920aae5 100644 --- a/core/src/main/java/org/bouncycastle/util/Pack.java +++ b/core/src/main/java/org/bouncycastle/util/Pack.java @@ -64,6 +64,14 @@ public static byte[] intToBigEndian(int n) return bs; } + public static void intToBigEndian(int n, byte[] bs) + { + bs[0] = (byte)(n >>> 24); + bs[1] = (byte)(n >>> 16); + bs[2] = (byte)(n >>> 8); + bs[3] = (byte)(n); + } + public static void intToBigEndian(int n, byte[] bs, int off) { bs[off] = (byte)(n >>> 24); @@ -230,6 +238,14 @@ public static void littleEndianToShort(byte[] bs, int bOff, short[] ns, int nOff } } + public static int littleEndianToInt24(byte[] bs, int off) + { + int n = bs[off] & 0xff; + n |= (bs[++off] & 0xff) << 8; + n |= (bs[++off] & 0xff) << 16; + return n; + } + public static int littleEndianToInt(byte[] bs, int off) { int n = bs[off] & 0xff; diff --git a/core/src/main/java/org/bouncycastle/util/Strings.java b/core/src/main/java/org/bouncycastle/util/Strings.java index 68075e5dd3..28f32f1079 100644 --- a/core/src/main/java/org/bouncycastle/util/Strings.java +++ b/core/src/main/java/org/bouncycastle/util/Strings.java @@ -333,7 +333,7 @@ public static String[] split(String input, char delimiter) while (moreTokens) { int tokenLocation = input.indexOf(delimiter); - if (tokenLocation > 0) + if (tokenLocation >= 0) { subString = input.substring(0, tokenLocation); v.addElement(subString); diff --git a/core/src/main/jdk1.1/java/security/SecurityUtil.java b/core/src/main/jdk1.1/java/security/SecurityUtil.java index 13c313cf69..fbc8d5a323 100644 --- a/core/src/main/jdk1.1/java/security/SecurityUtil.java +++ b/core/src/main/jdk1.1/java/security/SecurityUtil.java @@ -33,7 +33,7 @@ Provider getProvider() * * @return null if no algorithm found, an Implementation if it is. */ - static private Implementation getImplementation( + private static Implementation getImplementation( String baseName, String algorithm, Provider prov) diff --git a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java index 77429cdf41..1f511070b4 100644 --- a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java @@ -157,10 +157,10 @@ else if (algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_512) || algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_768) || algOID.equals(NISTObjectIdentifiers.id_alg_ml_kem_1024)) { - ASN1OctetString kyberKey = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); - MLKEMParameters kyberParams = Utils.mlkemParamsLookup(algOID); + ASN1OctetString mlkemKey = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); + MLKEMParameters mlkemParams = Utils.mlkemParamsLookup(algOID); - return new MLKEMPrivateKeyParameters(kyberParams, kyberKey.getOctets()); + return new MLKEMPrivateKeyParameters(mlkemParams, mlkemKey.getOctets()); } else if (Utils.mldsaParams.containsKey(algOID)) { diff --git a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java index bae4c435bc..9d600575c6 100644 --- a/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java +++ b/core/src/main/jdk1.1/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java @@ -108,12 +108,12 @@ public class PublicKeyFactory converters.put(BCObjectIdentifiers.picnicl5full, new PicnicConverter()); converters.put(BCObjectIdentifiers.falcon_512, new FalconConverter()); converters.put(BCObjectIdentifiers.falcon_1024, new FalconConverter()); - converters.put(NISTObjectIdentifiers.id_alg_ml_kem_512, new KyberConverter()); - converters.put(NISTObjectIdentifiers.id_alg_ml_kem_768, new KyberConverter()); - converters.put(NISTObjectIdentifiers.id_alg_ml_kem_1024, new KyberConverter()); - converters.put(BCObjectIdentifiers.kyber512_aes, new KyberConverter()); - converters.put(BCObjectIdentifiers.kyber768_aes, new KyberConverter()); - converters.put(BCObjectIdentifiers.kyber1024_aes, new KyberConverter()); + converters.put(NISTObjectIdentifiers.id_alg_ml_kem_512, new MLKEMConverter()); + converters.put(NISTObjectIdentifiers.id_alg_ml_kem_768, new MLKEMConverter()); + converters.put(NISTObjectIdentifiers.id_alg_ml_kem_1024, new MLKEMConverter()); + converters.put(BCObjectIdentifiers.kyber512_aes, new MLKEMConverter()); + converters.put(BCObjectIdentifiers.kyber768_aes, new MLKEMConverter()); + converters.put(BCObjectIdentifiers.kyber1024_aes, new MLKEMConverter()); converters.put(NISTObjectIdentifiers.id_ml_dsa_44, new MLDSAConverter()); converters.put(NISTObjectIdentifiers.id_ml_dsa_65, new MLDSAConverter()); converters.put(NISTObjectIdentifiers.id_ml_dsa_87, new MLDSAConverter()); @@ -351,16 +351,16 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } } - private static class KyberConverter + private static class MLKEMConverter extends SubjectPublicKeyInfoConverter { AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) throws IOException { - MLKEMParameters kyberParameters = Utils.mlkemParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); + MLKEMParameters mlkemParameters = Utils.mlkemParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); // we're a raw encoding - return new MLKEMPublicKeyParameters(kyberParameters, keyInfo.getPublicKeyData().getOctets()); + return new MLKEMPublicKeyParameters(mlkemParameters, keyInfo.getPublicKeyData().getOctets()); } } diff --git a/core/src/main/jdk1.4/org/bouncycastle/asn1/x500/style/IETFUtils.java b/core/src/main/jdk1.4/org/bouncycastle/asn1/x500/style/IETFUtils.java index 958de0c2ad..21c33697d3 100644 --- a/core/src/main/jdk1.4/org/bouncycastle/asn1/x500/style/IETFUtils.java +++ b/core/src/main/jdk1.4/org/bouncycastle/asn1/x500/style/IETFUtils.java @@ -131,32 +131,30 @@ private static int convertHex(char c) public static RDN[] rDNsFromString(String name, X500NameStyle x500Style) { - X500NameTokenizer tokenizer = new X500NameTokenizer(name); X500NameBuilder builder = new X500NameBuilder(x500Style); - addRDNs(x500Style, builder, tokenizer); + addRDNs(builder, new X500NameTokenizer(name)); - // TODO There's an unnecessary clone of the RDNs array happening here - return builder.build().getRDNs(); + return builder.buildRDNs(); } - private static void addRDNs(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer) + private static void addRDNs(X500NameBuilder builder, X500NameTokenizer tokenizer) { String token; while ((token = tokenizer.nextToken()) != null) { if (token.indexOf('+') >= 0) { - addMultiValuedRDN(style, builder, new X500NameTokenizer(token, '+')); + addMultiValuedRDN(builder, new X500NameTokenizer(token, '+')); } else { - addRDN(style, builder, token); + addRDN(builder, token); } } } - private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder builder, X500NameTokenizer tokenizer) + private static void addMultiValuedRDN(X500NameBuilder builder, X500NameTokenizer tokenizer) { String token = tokenizer.nextToken(); if (token == null) @@ -166,13 +164,14 @@ private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder build if (!tokenizer.hasMoreTokens()) { - addRDN(style, builder, token); + addRDN(builder, token); return; } Vector oids = new Vector(); Vector values = new Vector(); + X500NameStyle style = builder.getStyle(); do { collectAttributeTypeAndValue(style, oids, values, token); @@ -183,14 +182,14 @@ private static void addMultiValuedRDN(X500NameStyle style, X500NameBuilder build builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values)); } - private static void addRDN(X500NameStyle style, X500NameBuilder builder, String token) + private static void addRDN(X500NameBuilder builder, String token) { X500NameTokenizer tokenizer = new X500NameTokenizer(token, '='); String typeToken = nextToken(tokenizer, true); String valueToken = nextToken(tokenizer, false); - ASN1ObjectIdentifier oid = style.attrNameToOID(typeToken.trim()); + ASN1ObjectIdentifier oid = builder.getStyle().attrNameToOID(typeToken.trim()); String value = unescape(valueToken); builder.addRDN(oid, value); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java b/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java index 6d72137fa5..2c5d1570a2 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/DERApplicationSpecificTest.java @@ -100,7 +100,7 @@ public void performTest() fail("wrong tag detected"); } - ASN1Integer value = new ASN1Integer(9); + ASN1Integer value = ASN1Integer.valueOf(9); DERTaggedObject tagged = new DERTaggedObject(false, BERTags.APPLICATION, 3, value); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java b/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java index 904b76ce79..49434823d1 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/DERPrivateTest.java @@ -93,7 +93,7 @@ public void performTest() fail("wrong tag detected"); } - ASN1Integer value = new ASN1Integer(9); + ASN1Integer value = ASN1Integer.valueOf(9); ASN1TaggedObject tagged = new DERTaggedObject(false, BERTags.PRIVATE, 3, value); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java b/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java index 170eb1435e..0ff80b0c90 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/DLExternalTest.java @@ -64,7 +64,7 @@ public void testInstantiationByVector() { isEquals("check message", "too few objects in input sequence", iae.getMessage()); } - vec.add(new DLTaggedObject(true, 0, new ASN1Integer(1234567890L))); + vec.add(new DLTaggedObject(true, 0, ASN1Integer.valueOf(1234567890))); DLExternal dle = new DLExternal(new DLSequence(vec)); @@ -81,9 +81,9 @@ public void testInstantiationByVector() isEquals("check value of external content", "1234567890", ((ASN1Integer)dle.getExternalContent()).getValue().toString()); vec = new ASN1EncodableVector(); - vec.add(new ASN1Integer(9L)); + vec.add(ASN1Integer.valueOf(9)); vec.add(new DERUTF8String("something completely different")); - vec.add(new DLTaggedObject(true, 0, new ASN1Integer(1234567890L))); + vec.add(new DLTaggedObject(true, 0, ASN1Integer.valueOf(1234567890))); dle = new DLExternal(vec); isEquals("check direct reference", null, dle.getDirectReference()); @@ -210,7 +210,7 @@ private ASN1EncodableVector createRealDataExample(int encoding) ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new ASN1ObjectIdentifier("2.1.1")); - vec.add(new ASN1Integer(9)); + vec.add(ASN1Integer.valueOf(9)); vec.add(new DERUTF8String("example data representing the User Data of an OSI.6 ConnectP containing an MSBind with username and password")); ASN1EncodableVector objectNameVec = new ASN1EncodableVector(); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java b/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java index bdfb74969a..6392c748c8 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java @@ -62,7 +62,7 @@ public TestResult perform() new DERGeneralizedTime("20070315173729Z"), new DERGeneralString("hello world"), new DERIA5String("hello"), - new ASN1Integer(1000), + ASN1Integer.valueOf(1000), DERNull.INSTANCE, new DERNumericString("123456"), new ASN1ObjectIdentifier("1.1.1.10000.1"), diff --git a/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java b/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java index 86acbe2dcf..0a4c4aa5b3 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/GenerationTest.java @@ -83,7 +83,7 @@ private void tbsV1CertGen() Date startDate = new Date(1000); Date endDate = new Date(12000); - gen.setSerialNumber(new ASN1Integer(1)); + gen.setSerialNumber(ASN1Integer.ONE); gen.setStartDate(new Time(startDate)); gen.setEndDate(new Time(endDate)); @@ -139,7 +139,7 @@ private void tbsV3CertGen() Date startDate = new Date(1000); Date endDate = new Date(2000); - gen.setSerialNumber(new ASN1Integer(2)); + gen.setSerialNumber(ASN1Integer.TWO); gen.setStartDate(new Time(startDate)); gen.setEndDate(new Time(endDate)); @@ -149,7 +149,7 @@ private void tbsV3CertGen() gen.setSignature(new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption, DERNull.INSTANCE)); - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), new ASN1Integer(3)); + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), ASN1Integer.THREE); gen.setSubjectPublicKeyInfo(info); @@ -191,7 +191,7 @@ private void tbsV3CertGenWithNullSubject() Date startDate = new Date(1000); Date endDate = new Date(2000); - gen.setSerialNumber(new ASN1Integer(2)); + gen.setSerialNumber(ASN1Integer.TWO); gen.setStartDate(new Time(startDate)); gen.setEndDate(new Time(endDate)); @@ -200,7 +200,7 @@ private void tbsV3CertGenWithNullSubject() gen.setSignature(new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption, DERNull.INSTANCE)); - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), new ASN1Integer(3)); + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), ASN1Integer.THREE); gen.setSubjectPublicKeyInfo(info); @@ -253,7 +253,7 @@ private void tbsV2CertListGen() gen.setIssuer(new X500Name("CN=AU,O=Bouncy Castle")); - gen.addCRLEntry(new ASN1Integer(1), new Time(new Date(1000)), CRLReason.aACompromise); + gen.addCRLEntry(ASN1Integer.ONE, new Time(new Date(1000)), CRLReason.aACompromise); gen.setNextUpdate(new Time(new Date(2000))); @@ -264,19 +264,19 @@ private void tbsV2CertListGen() // // extensions // - SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), new ASN1Integer(3)); + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(BigInteger.valueOf(1), BigInteger.valueOf(2))), ASN1Integer.THREE); ExtensionsGenerator extGen = new ExtensionsGenerator(); extGen.addExtension(Extension.authorityKeyIdentifier, true, createAuthorityKeyId(info, new X500Name("CN=AU,O=Bouncy Castle,OU=Test 2"), 2)); extGen.addExtension(Extension.issuerAlternativeName, false, new GeneralNames(new GeneralName(new X500Name("CN=AU,O=Bouncy Castle,OU=Test 3")))); - extGen.addExtension(Extension.cRLNumber, false, new ASN1Integer(1)); + extGen.addExtension(Extension.cRLNumber, false, ASN1Integer.ONE); extGen.addExtension(Extension.issuingDistributionPoint, true, IssuingDistributionPoint.getInstance(new DERSequence())); isTrue(extGen.hasExtension(Extension.cRLNumber)); isTrue(!extGen.hasExtension(Extension.freshestCRL)); - isEquals(new Extension(Extension.cRLNumber, false, new ASN1Integer(1).getEncoded()), extGen.getExtension(Extension.cRLNumber)); + isEquals(new Extension(Extension.cRLNumber, false, ASN1Integer.ONE.getEncoded()), extGen.getExtension(Extension.cRLNumber)); Extensions ex = extGen.generate(); @@ -292,9 +292,9 @@ private void tbsV2CertListGen() } // extGen - check replacement. - extGen.replaceExtension(Extension.cRLNumber, false, new ASN1Integer(2)); + extGen.replaceExtension(Extension.cRLNumber, false, ASN1Integer.TWO); - isEquals(new Extension(Extension.cRLNumber, false, new ASN1Integer(2).getEncoded()), extGen.getExtension(Extension.cRLNumber)); + isEquals(new Extension(Extension.cRLNumber, false, ASN1Integer.TWO.getEncoded()), extGen.getExtension(Extension.cRLNumber)); // extGen - check remove. extGen.removeExtension(Extension.cRLNumber); @@ -318,11 +318,11 @@ private void tbsV2CertListGen() // // check we can add a custom reason // - gen.addCRLEntry(new ASN1Integer(1), new Time(new Date(1000)), CRLReason.aACompromise); + gen.addCRLEntry(ASN1Integer.ONE, new Time(new Date(1000)), CRLReason.aACompromise); // // check invalidity date - gen.addCRLEntry(new ASN1Integer(2), new Time(new Date(1000)), CRLReason.affiliationChanged, new ASN1GeneralizedTime(new Date(2000))); + gen.addCRLEntry(ASN1Integer.TWO, new Time(new Date(1000)), CRLReason.affiliationChanged, new ASN1GeneralizedTime(new Date(2000))); TBSCertList crl = gen.generateTBSCertList(); @@ -331,7 +331,7 @@ private void tbsV2CertListGen() { TBSCertList.CRLEntry entry = entries[i]; - if (entry.getUserCertificate().equals(new ASN1Integer(1))) + if (entry.getUserCertificate().equals(ASN1Integer.ONE)) { Extensions extensions = entry.getExtensions(); Extension ext = extensions.getExtension(Extension.reasonCode); @@ -343,7 +343,7 @@ private void tbsV2CertListGen() fail("reason code mismatch"); } } - else if (entry.getUserCertificate().equals(new ASN1Integer(2))) + else if (entry.getUserCertificate().equals(ASN1Integer.TWO)) { Extensions extensions = entry.getExtensions(); Extension ext = extensions.getExtension(Extension.reasonCode); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java b/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java index faff2ffb3c..3fb70f17e0 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/GetInstanceTest.java @@ -328,7 +328,7 @@ public void testGetInstance() doFullGetInstanceTest(DERT61String.class, new DERT61String("hello world")); doFullGetInstanceTest(DERVisibleString.class, new DERVisibleString("hello world")); - doFullGetInstanceTest(ASN1Integer.class, new ASN1Integer(1)); + doFullGetInstanceTest(ASN1Integer.class, ASN1Integer.ONE); doFullGetInstanceTest(ASN1GeneralizedTime.class, new ASN1GeneralizedTime(new Date())); doFullGetInstanceTest(ASN1UTCTime.class, new ASN1UTCTime(new Date())); doFullGetInstanceTest(ASN1Enumerated.class, new ASN1Enumerated(1)); @@ -362,7 +362,7 @@ public void testGetInstance() BasicOCSPResponse.getInstance(null); BasicOCSPResponse.getInstance(null); - doFullGetInstanceTest(CertID.class, new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new DEROctetString(new byte[1]), new DEROctetString(new byte[1]), new ASN1Integer(1))); + doFullGetInstanceTest(CertID.class, new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new DEROctetString(new byte[1]), new DEROctetString(new byte[1]), ASN1Integer.ONE)); CertStatus.getInstance(null); CertStatus.getInstance(null); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/KMACParamsTest.java b/core/src/test/java/org/bouncycastle/asn1/test/KMACParamsTest.java index 91fff5a722..10d6453981 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/KMACParamsTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/KMACParamsTest.java @@ -19,25 +19,25 @@ public void performTest() isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(256).getEncoded(), new DERSequence().getEncoded())); isTrue(Arrays.areEqual(new KMACwithSHAKE256_params(512).getEncoded(), new DERSequence().getEncoded())); - isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(512).getEncoded(), new DERSequence(new ASN1Integer(512)).getEncoded())); - isTrue(Arrays.areEqual(new KMACwithSHAKE256_params(256).getEncoded(), new DERSequence(new ASN1Integer(256)).getEncoded())); + isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(512).getEncoded(), new DERSequence(ASN1Integer.valueOf(512)).getEncoded())); + isTrue(Arrays.areEqual(new KMACwithSHAKE256_params(256).getEncoded(), new DERSequence(ASN1Integer.valueOf(256)).getEncoded())); - isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(512).getEncoded(), KMACwithSHAKE128_params.getInstance(new DERSequence(new ASN1Integer(512))).getEncoded())); - isTrue(Arrays.areEqual(new KMACwithSHAKE256_params(256).getEncoded(), KMACwithSHAKE256_params.getInstance(new DERSequence(new ASN1Integer(256))).getEncoded())); + isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(512).getEncoded(), KMACwithSHAKE128_params.getInstance(new DERSequence(ASN1Integer.valueOf(512))).getEncoded())); + isTrue(Arrays.areEqual(new KMACwithSHAKE256_params(256).getEncoded(), KMACwithSHAKE256_params.getInstance(new DERSequence(ASN1Integer.valueOf(256))).getEncoded())); byte[] customizationString = Strings.toByteArray("hello, world!"); isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(512, customizationString).getEncoded(), new DERSequence( - new ASN1Encodable[] { new ASN1Integer(512), new DEROctetString(customizationString) }).getEncoded())); + new ASN1Encodable[] { ASN1Integer.valueOf(512), new DEROctetString(customizationString) }).getEncoded())); isTrue(Arrays.areEqual(new KMACwithSHAKE256_params(256, customizationString).getEncoded(), new DERSequence( - new ASN1Encodable[] { new ASN1Integer(256), new DEROctetString(customizationString) }).getEncoded())); + new ASN1Encodable[] { ASN1Integer.valueOf(256), new DEROctetString(customizationString) }).getEncoded())); isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(512, customizationString).getEncoded(), KMACwithSHAKE128_params.getInstance( - new DERSequence(new ASN1Encodable[] { new ASN1Integer(512), new DEROctetString(customizationString) })).getEncoded())); + new DERSequence(new ASN1Encodable[] { ASN1Integer.valueOf(512), new DEROctetString(customizationString) })).getEncoded())); isTrue(Arrays.areEqual(new KMACwithSHAKE256_params(256, customizationString).getEncoded(), KMACwithSHAKE256_params.getInstance(new DERSequence( - new ASN1Encodable[] { new ASN1Integer(256), new DEROctetString(customizationString) })).getEncoded())); + new ASN1Encodable[] { ASN1Integer.valueOf(256), new DEROctetString(customizationString) })).getEncoded())); isTrue(Arrays.areEqual(new KMACwithSHAKE128_params(256, customizationString).getEncoded(), new DERSequence( new ASN1Encodable[] { new DEROctetString(customizationString) }).getEncoded())); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/PolicyConstraintsTest.java b/core/src/test/java/org/bouncycastle/asn1/test/PolicyConstraintsTest.java index bc0d2f09bd..3359867898 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/PolicyConstraintsTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/PolicyConstraintsTest.java @@ -44,7 +44,7 @@ public void performTest() isTrue("encoding test", Arrays.areEqual( new PolicyConstraints(BigInteger.valueOf(1), null).getEncoded(), - new DERSequence(new DERTaggedObject(false, 0, new ASN1Integer(1))).getEncoded())); + new DERSequence(new DERTaggedObject(false, 0, ASN1Integer.ONE)).getEncoded())); } public static void main( diff --git a/core/src/test/java/org/bouncycastle/asn1/test/SetTest.java b/core/src/test/java/org/bouncycastle/asn1/test/SetTest.java index d1f1707cd0..5d720308fb 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/SetTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/SetTest.java @@ -48,13 +48,13 @@ public void performTest() v.add(new DEROctetString(data)); v.add(new DERBitString(data)); - v.add(new ASN1Integer(100)); + v.add(ASN1Integer.valueOf(100)); v.add(ASN1Boolean.getInstance(true)); checkedSortedSet(0, new DERSet(v)); v = new ASN1EncodableVector(); - v.add(new ASN1Integer(100)); + v.add(ASN1Integer.valueOf(100)); v.add(ASN1Boolean.getInstance(true)); v.add(new DEROctetString(data)); v.add(new DERBitString(data)); @@ -65,7 +65,7 @@ public void performTest() v.add(ASN1Boolean.getInstance(true)); v.add(new DEROctetString(data)); v.add(new DERBitString(data)); - v.add(new ASN1Integer(100)); + v.add(ASN1Integer.valueOf(100)); checkedSortedSet(2, new DERSet(v)); @@ -73,7 +73,7 @@ public void performTest() v = new ASN1EncodableVector(); v.add(new DERBitString(data)); v.add(new DEROctetString(data)); - v.add(new ASN1Integer(100)); + v.add(ASN1Integer.valueOf(100)); v.add(ASN1Boolean.getInstance(true)); checkedSortedSet(3, new DERSet(v)); @@ -81,7 +81,7 @@ public void performTest() v = new ASN1EncodableVector(); v.add(new DEROctetString(data)); v.add(new DERBitString(data)); - v.add(new ASN1Integer(100)); + v.add(ASN1Integer.valueOf(100)); v.add(ASN1Boolean.getInstance(true)); ASN1Set s = new BERSet(v); diff --git a/core/src/test/java/org/bouncycastle/asn1/test/TagTest.java b/core/src/test/java/org/bouncycastle/asn1/test/TagTest.java index 4f6edad492..b225c1b43b 100644 --- a/core/src/test/java/org/bouncycastle/asn1/test/TagTest.java +++ b/core/src/test/java/org/bouncycastle/asn1/test/TagTest.java @@ -110,7 +110,7 @@ public void performTest() } } - tagged = new DERTaggedObject(false, 34, new DERTaggedObject(true, 1000, new ASN1Integer(1))); + tagged = new DERTaggedObject(false, 34, new DERTaggedObject(true, 1000, ASN1Integer.ONE)); if (!areEqual(taggedInteger, tagged.getEncoded())) { fail("incorrect encoding for implicit explicit tagged integer"); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/DHKEKGeneratorTest.java b/core/src/test/java/org/bouncycastle/crypto/test/DHKEKGeneratorTest.java index 8a83d2a395..d43b81c96f 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/DHKEKGeneratorTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/DHKEKGeneratorTest.java @@ -1,5 +1,7 @@ package org.bouncycastle.crypto.test; +import java.security.SecureRandom; + import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.crypto.DerivationFunction; @@ -16,6 +18,8 @@ public class DHKEKGeneratorTest extends SimpleTest { + private static final SecureRandom RANDOM = new SecureRandom(); + private byte[] seed1 = Hex.decode("000102030405060708090a0b0c0d0e0f10111213"); private ASN1ObjectIdentifier alg1 = PKCSObjectIdentifiers.id_alg_CMS3DESwrap; private byte[] result1 = Hex.decode("a09661392376f7044d9052a397883246b67f5f1ef63eb5fb"); @@ -45,7 +49,8 @@ private void checkMask( DerivationParameters params, byte[] result) { - byte[] data = new byte[result.length]; + byte[] data = new byte[result.length]; + RANDOM.nextBytes(data); kdf.init(params); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/ECDHKEKGeneratorTest.java b/core/src/test/java/org/bouncycastle/crypto/test/ECDHKEKGeneratorTest.java index d75b13962d..6e81f5ccb0 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/ECDHKEKGeneratorTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/ECDHKEKGeneratorTest.java @@ -1,5 +1,7 @@ package org.bouncycastle.crypto.test; +import java.security.SecureRandom; + import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; @@ -17,6 +19,8 @@ public class ECDHKEKGeneratorTest extends SimpleTest { + private static final SecureRandom RANDOM = new SecureRandom(); + private byte[] seed1 = Hex.decode("db4a8daba1f98791d54e940175dd1a5f3a0826a1066aa9b668d4dc1e1e0790158dcad1533c03b44214d1b61fefa8b579"); private ASN1ObjectIdentifier alg1 = NISTObjectIdentifiers.id_aes256_wrap; private byte[] result1 = Hex.decode("8ecc6d85caf25eaba823a7d620d4ab0d33e4c645f2"); @@ -46,7 +50,8 @@ private void checkMask( DerivationParameters params, byte[] result) { - byte[] data = new byte[result.length]; + byte[] data = new byte[result.length]; + RANDOM.nextBytes(data); kdf.init(params); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/RSABlindedTest.java b/core/src/test/java/org/bouncycastle/crypto/test/RSABlindedTest.java index 27a9aeb449..9327710476 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/RSABlindedTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/RSABlindedTest.java @@ -1,5 +1,8 @@ package org.bouncycastle.crypto.test; +import java.math.BigInteger; +import java.security.SecureRandom; + import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.InvalidCipherTextException; @@ -13,9 +16,6 @@ import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; -import java.math.BigInteger; -import java.security.SecureRandom; - public class RSABlindedTest extends SimpleTest { @@ -426,6 +426,29 @@ public void performTest() { // expected } + + // null public exponent + privParameters = new RSAPrivateCrtKeyParameters(mod, null, privExp, p, q, pExp, qExp, crtCoef); + + RSABlindedEngine bEng = new RSABlindedEngine(); + + bEng.init(true, privParameters); + + bEng.processBlock(new byte[]{ 1 }, 0, 1); + + privParameters = new RSAPrivateCrtKeyParameters(mod, null, null, p, q, pExp, qExp, crtCoef); + + bEng.init(true, privParameters); + + try + { + bEng.processBlock(new byte[]{1}, 0, 1); + fail("no exception"); + } + catch (IllegalStateException e) + { + // ignore - expected. + } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java index 10041d03bb..963d14d39e 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/HQCTest.java @@ -1,15 +1,13 @@ package org.bouncycastle.pqc.crypto.test; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; import java.security.SecureRandom; -import java.util.HashMap; import junit.framework.TestCase; -import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.bouncycastle.crypto.EncapsulatedSecretExtractor; +import org.bouncycastle.crypto.EncapsulatedSecretGenerator; import org.bouncycastle.crypto.digests.SHAKEDigest; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.pqc.crypto.hqc.HQCKEMExtractor; import org.bouncycastle.pqc.crypto.hqc.HQCKEMGenerator; import org.bouncycastle.pqc.crypto.hqc.HQCKeyGenerationParameters; @@ -17,14 +15,6 @@ import org.bouncycastle.pqc.crypto.hqc.HQCParameters; import org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters; import org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters; -import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; -import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; -import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; -import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; -import org.bouncycastle.test.TestResourceFinder; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.encoders.Hex; -import org.bouncycastle.util.test.FixedSecureRandom; public class HQCTest extends TestCase @@ -36,18 +26,6 @@ public static void main(String[] args) test.testVectors(); } -// static final String[] files = new String[]{ -// "PQCkemKAT_2321.rsp", -// "PQCkemKAT_4602.rsp", -// "PQCkemKAT_7333.rsp", -// }; -// -// HQCParameters[] PARAMETER_SETS = new HQCParameters[]{ -// HQCParameters.hqc128, -// HQCParameters.hqc192, -// HQCParameters.hqc256 -// }; - @Override public String getName() { @@ -67,93 +45,63 @@ public void testVectors() "PQCkemKAT_7333.rsp", }; - HQCParameters[] listParams = new HQCParameters[]{ + final HQCParameters[] listParams = new HQCParameters[]{ HQCParameters.hqc128, HQCParameters.hqc192, HQCParameters.hqc256 }; - for (int fileIndex = 0; fileIndex < files.length; fileIndex++) + TestUtils.testTestVector(true, true, "pqc/crypto/hqc", files, new TestUtils.KeyEncapsulationOperation() { - String name = files[fileIndex]; - //System.out.println(files[fileIndex]); - InputStream src = TestResourceFinder.findTestResource("pqc/crypto/hqc", name); - BufferedReader bin = new BufferedReader(new InputStreamReader(src)); - - String line = null; - HashMap buf = new HashMap(); - TestSampler sampler = new TestSampler(); - while ((line = bin.readLine()) != null) + int sessionKeySize = 0; + + @Override + public SecureRandom getSecureRandom(byte[] seed) { - line = line.trim(); - - if (line.startsWith("#")) - { - continue; - } - if (line.length() == 0) - { - if (buf.size() > 0) - { - String count = (String)buf.get("count"); - if (sampler.skipTest(count)) - { - continue; - } - // System.out.println("test case: " + count); - - byte[] seed = Hex.decode((String)buf.get("seed")); // seed for bike secure random - byte[] pk = Hex.decode((String)buf.get("pk")); // public key - byte[] sk = Hex.decode((String)buf.get("sk")); // private key - byte[] ct = Hex.decode((String)buf.get("ct")); // ciphertext - byte[] ss = Hex.decode((String)buf.get("ss")); // session key - - HQCParameters parameters = listParams[fileIndex]; - SecureRandom random = new Shake256SecureRandom(seed); - HQCKeyPairGenerator hqcKeyGen = new HQCKeyPairGenerator(); - HQCKeyGenerationParameters genParam = new HQCKeyGenerationParameters(random, parameters); - - // - // Generate keys and test. - // - - // KEM Keypair - hqcKeyGen.init(genParam); - AsymmetricCipherKeyPair pair = hqcKeyGen.generateKeyPair(); - - HQCPublicKeyParameters generatedPk = (HQCPublicKeyParameters)PublicKeyFactory.createKey(SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((HQCPublicKeyParameters)pair.getPublic())); - HQCPrivateKeyParameters generatedSk = (HQCPrivateKeyParameters)PrivateKeyFactory.createKey(PrivateKeyInfoFactory.createPrivateKeyInfo((HQCPrivateKeyParameters)pair.getPrivate())); - - assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, generatedPk.getPublicKey())); - assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, generatedSk.getPrivateKey())); - - // KEM Encapsulation - HQCKEMGenerator hqcKemGenerator = new HQCKEMGenerator(random); - SecretWithEncapsulation secretWithEnc = hqcKemGenerator.generateEncapsulated(generatedPk); - byte[] secret = secretWithEnc.getSecret(); - byte[] c = secretWithEnc.getEncapsulation(); - - assertTrue(name + " " + count + ": ciphertext", Arrays.areEqual(c, ct)); - assertTrue(name + " " + count + ": kem_dec ss", Arrays.areEqual(secret, 0, secret.length, ss, 0, secret.length)); - - // KEM Decapsulation - HQCKEMExtractor bikekemExtractor = new HQCKEMExtractor(generatedSk); - byte[] dec_key = bikekemExtractor.extractSecret(c); - - assertEquals(parameters.getSessionKeySize(), secret.length * 8); - assertTrue(name + " " + count + ": kem_dec key", Arrays.areEqual(dec_key, secret)); - } - buf.clear(); - continue; - } - int a = line.indexOf("="); - if (a > -1) - { - buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); - } + return new Shake256SecureRandom(seed); } - // System.out.println("Testing successful!"); - } + + @Override + public AsymmetricCipherKeyPairGenerator getAsymmetricCipherKeyPairGenerator(int fileIndex, SecureRandom random) + { + HQCParameters parameters = listParams[fileIndex]; + sessionKeySize = parameters.getSessionKeySize(); + HQCKeyPairGenerator hqcKeyGen = new HQCKeyPairGenerator(); + HQCKeyGenerationParameters genParam = new HQCKeyGenerationParameters(random, parameters); + hqcKeyGen.init(genParam); + return hqcKeyGen; + } + + @Override + public byte[] getPublicKeyEncoded(AsymmetricKeyParameter pubParams) + { + return ((HQCPublicKeyParameters)pubParams).getPublicKey(); + } + + @Override + public byte[] getPrivateKeyEncoded(AsymmetricKeyParameter privParams) + { + return ((HQCPrivateKeyParameters)privParams).getPrivateKey(); + } + + @Override + public EncapsulatedSecretGenerator getKEMGenerator(SecureRandom random) + { + return new HQCKEMGenerator(random); + } + + @Override + public EncapsulatedSecretExtractor getKEMExtractor(AsymmetricKeyParameter privParams) + { + return new HQCKEMExtractor((HQCPrivateKeyParameters)privParams); + } + + @Override + public int getSessionKeySize() + { + return sessionKeySize; + } + }); } private static class Shake256SecureRandom @@ -161,7 +109,7 @@ private static class Shake256SecureRandom { private final SHAKEDigest digest = new SHAKEDigest(256); - public Shake256SecureRandom(byte[] seed) + Shake256SecureRandom(byte[] seed) { digest.update(seed, 0, seed.length); digest.update((byte) 0); diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java index 36ed800b2b..c3f312a24a 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/MLKEMTest.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.Map; +import junit.framework.Assert; import junit.framework.TestCase; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; @@ -34,6 +35,11 @@ public class MLKEMTest extends TestCase { + private static byte[] okayKey = Hex.decode("29F853ECE08908E99D4B7195B89C296037B786E3000CA95607D80288A62EBDB53E5AD7A4BC716AE3BC0200788D7FBA9E49D5AAAA0A46E7A6C829A7B64869C458CACDB9043D350BC920D29E1D1B8E5ED57D83132AA6119C33770A56EB64511579FF2404F4CAA6CA8026BC647EA1692143139D4B5526006C38E87C1AC88CB615B87910E75371F97376938533B9720810B63D7354CE6B726184A392D90AF5F5821179C0ED4A519C4530818788CD877027369B5C8855486C2E8DE9BD7A2835A5D0248B772DFBE26BFA4049D0BC51EDCB9C51FAAFF638CB45399B8186C12E8119D5CBBCADE116FE1ACB097C8280343A3E666F6C5B89DB1070E698185D290429107712A46A3D057233B90FBC9A475CA73D3FF2743E54CEB255AF1809209D042E54D4C099D6C3B46868CBC64F00C5B352831C28C28260E40233CA62F5DC814C0809A9653D63CB756032BD9322544A199EF6E696AB026BA2701CE4D2A13850275BDA905A05130B2CB1E7410F46523DB54646E94C508CF548190A507174CA8B481BDC14C27B9267D8F428C0F73EBA769F35398824B2C4D6C171A1CA7A9DE0A315FA75ECD477B10969956B34F5188BA290390755066BFA8FB4E9BAE097A59243CE0DC57089E022C8D52A19D03F7EB23141B51A44BC1B1C0BA52A70AA1B8A61654CC54079A3AABC4D86E3C046880CDA9BCCE3A609E6A1149DFB6931E91D743BCBCDF6A963175FB48520FFD22885D0BCC59393F487133A5A0E115A02CD6049C06C8FF4D8A221E20D3F23C905501180F878C4D52C65C5A7FD745592CC38F5266918808B730138CEE47B0914544A653DDACB729581AC7296A7A5C90009DB63EDFAA45B6086BEA186983487A0E530D069AB99A10DC2F59894A77D15A7933AF23ECD283962E778BCAB985B2BA7DA84C0E10C165500A1A93427B976516E867A94095F30D406C209126789ADBE325D652ACD09B4B104A431ED4691F7A5CD15279A36E939A80C91C6468BF73811F103CA405C93CAC493245516ABCAC7B3F90CD2F030BE6461A18818C3983B03106D2D343D88877C41B9C329CB76B7DB2720D0157A04141459032AF4017D09D47B472F4CF643436ABF8D29AC9F7E27C7D9EB181F5AC93833D930C05D3E"); + private static byte[] tooLargeKey = Hex.decode("00615CA0D7AD5C0C84A7F77A9ACA3C32E17732C42EDC46249490021B9822D06361705ABFFC28730CE741B144A27A5748DE280CD253575EA6AF87C12E9ED6029825AB2F14C482E86DBB020257A25A33F38524858DBE4305A6B13859382615C6CCF7A997085384F8F0401F63127F5358D37236D978377365023FF659B3470195C43824441DA37641931041039093B185145C8644846B57EBF3862DC41AB7E54ABD0730BCC25B369C8B86E2165C73691F1863887071A77CAFFE39B537026991153A92D90E0568729F4C568895B965B8A1030A93DBA93672C2B9C5331491F442069550E4555F085B94F9F1611A028776361A6696671207B18803BE44395C7A560BD675B94ED0C0FFC97253E58FE2FBBBAACA802BB98F5E2B3DD810AE2CA91C00088B7D3175A2A65468A872917400163337BE503BEC2A24D798CF85A6653470AA5F0635447C94E73CA0FD09A2BD104432768F239B9633DC943BD052A8934D38D408BA38B57947699DF3783871CC23A46AA871BAA096A7DE77CF4320B2AF26A40F656351F90DFEB11088E85E6E181F42475324240288F13B5DE310E07C698914B8B9355416A69219D92315B9C3421205B0698D6AE3161AD18ECC325C3BC4BDE37002C4AA128C4C4FD4EAB040831264684ACA88A0D9C4616824085CE9A3A0C37C1148B41EA6C242B77E277C4A867113D9B3920354BE976C68ABD89E76819E7C3573F79A85D9A1778DA81D871838BBB43870CB786525267FF009B21A3275B7958936BABB7020D7F832362AA95E7761B9A82FD813266C709D4AC778632298F5800079D88A447C7A6B004843831775499C62A553BCF302FB0556CCA10577F24C81A651232BC9A5E97D37FC046498BCCFC69F7E4CBF890CC4DF5AA5E76C14371C38C5A348D1303C154C11899B7E9AA34D806275D6AB0E1E7B3A0BE6B48FC21475C4B5ED3B6AAFC23ADFBB7E33E501B7545B71446BABB6680A7316C39994DA351E36D228572080DFB47E0FBC12D24A842847109700309CF47B0F338389DAC6EFF534FA2251DA7773DD6845112843B95739D8F2109A91B078BAAC3612230D77569BA22138F9AB3FA02DFACA54C943920D254550C863261C771C32F6BC643A77D9C279F08AAC3E51F90DFEB11088E85E6E181F42475324240288F13B5DE310E07C698914B8B9355416A69219D92315B9C3421205B0698D6AE3161AD18ECC325C3BC4BDE37002C4AA128C4C4FD4EAB040831264684ACA88A0D9C4616824085CE9A3A0C37C1148B41EA6C242B77E277C4A867113D9B3920354BE976C68ABD89E76819E7C3573F79A85D9A1778DA81D871838BBB43870CB786525267FF009B21A3275B7958936BABB7020D7F832362AA95E7761B9A82FD813266C709D4AC778632298F5800079D88A447C7A6B004843831775499C62A553BCF302FB0556CCA10577F24C81A651232BC9A5E97D37FC046498BCCFC69F7E4CBF890CC4DF5AA5E76C14371C38C5A348D1303C154C11899B7E9AA34D806275D6AB0E1E7B3A0BE6B48FC21475C4B5ED3B6AAFC23ADFBB7E33E501B7545B71446BABB6680A7316C39994DA351E36D228572080DFB47E0FBC12D24A842847109700309CF47B0F338389DAC6EFF534FA2251DA7773DD6845112843B95739D8F2109A91B078BAAC3612230D77569BA22138F9AB3FA02DFACA54C943920D254550C863261C771C32F6BC643A77D9C279F08AAC3E"); + + private static byte[] faultyPrivateKey = Hex.decode("F57A2F125726FF2B75F19321D55A7AA33142A1BA9B8C1A1DDF9068D4759BFDFAB942A0AA90710033846B195BA44FC1762CA26C8AC0639BC1ADC2DC0E49CC6559830AF9463401EA181FEC83BD69594E3911108A929E1C2AD0F65AD60C5DE509BE8A966FE1F3452097C0BC186F6DA467F84A4A64A7B657D06D96E1A411611D39A3726752C30E48244CD675B7AC7F993C2EF5CCC5C598123024AFD3403DAA4A1541E1A8EE797B06BA5A9A01C0D2340B0122A379FB8F1EF73D2E46117F6B6FF23468C1D43413D4B0760A49B7D6BFE0784D1A646209C719C9E66147467E940163D03A0D4106C019E743F864A809F9BFD2E8C40AD185A428B1AAEC7510ECCC039A62E2E27472F77B451A8C5BFC1AF9D3C632B006CEE13A9B6B8F3280889A0515CC54BD2D676BB930B0C440771D965E4CA92942F9705D4BA535D43D18F94957BA285C0B5BF0F40080B1B42E82446A64C3B2707ADB41954F803B72884A13EBABC2801385928FF3890607B3C60FC16155A51C20BCB3BF3ACD07559F4BA67CE349AD5BD86106D01C19E222EFF33768782BBFF10D07D42045C69F68126241C985D1E3C1E39195DC133B8E6913E17359A331706C882D82527BDC90A0C7B223B4C30537CCC986E17C09513B1FF9A026A80A9358CAFA97A0C6D65BDAF471880C5B7A69882DAA2AE5C9223024AF3AA38FDFB1960F2527F7C03AAEB24E071BB4AE7CC170B4C9A302CF6ECA4FFBC96B3A801FE643CA65605A3CE5BC0944C1E234BA9EB9C7294543064309E266108E21110C5251648BB0AB449832115DF6D5538004581B371E6C779AD3949B2E4BA041E218EB853D172341C426B0DD1C3CB1B3283F27C716C288C1CA3C6C4BAE3C8B7AFC480565B13FA13A0CED8B2C0BBC83D26C0EC81C9EA25B9663710E51A811D8E398F4BB761DD862BF30502873C04A3B412BE20C8C2819312245288AC6DF74AE1B85BA217ABE08F465B12CAFF664B3693CAA5688C05F2A2070C307DAFA7F37BBAB87F11708F04E10175A74D6ABD7D09D8A0862AC487AED60BE508B28A52B1FC394A176C6A89F68BCC2217B4B463EF631C9821B3D71216CDE75A7D8763665956670ECBAE9B13A73899ED68264E65298B0B8256B713FE62470DDD3443E103AA679B8A6B3A8D690A9A655BFD0AA0A1030C5C57A1E6419114555605D1197F45C9258C617B28983C4257B67F688087A77A0990E6D11982589BF1FD424CDF73B156896FA534530416D1AB75915B3460AA295216C362C48A2B9944D94F4A00AEB5A9991979BD9B7859C881B5B3254F59079DC2DB209CE73AAC00D945713D46A62D9013F909A7E88B925704669B5356F851A99F77181215D0A73351871C853847B7BB3715E4892FDFC9466A4C7EAA83F0A9468FBCA6684786C61607A6FA1875C6043092B3DD6D5127C92559A9157F6DC1CD999B86A096A5D1524A578CA36C667C3F092DA3AA889319669469648C4BA920B53843686A18A8246B3B5A659C936EA0D0B01147B5832214488139224F9595FDB9151AE3621E1DCAAA03213B0C36CEF674FCF0517E313CF34E2A894FC063647408D239AF66C40ABF49E88268A1BBC2CC4CABF45C11A6379CEA9D326F685ADF021969942AD4A2A324B6C9033720A55F280A01648BA614C2DE6AB110AA71F56379910CEED337A64599222888E18598078E6A2B7D4497024A0CDD0B382C371592A65BA538DC025B82361C9AF7334A8D6C259A57F3EBC4B21F01F0BE6346B2CB25EB10A41D5AA2B28255DA750BAA89C2C0982A5C2B5C2292B98E91C922848DC2036D96001BE1208C7A1C8BCF29F4CA463DFB964D07443DBBA9CF4DC7A90342DAE70C2703A9FBE324C08AA2B7C86A94E6A3D7760BD40366E1336A56D57C29225363F6A5F8E91216ED2574037B028B3A69E3C0511B08DD6E07D0BEC5A6DF0A2111AAD9AA58EFAAB4596E25099930A56809CE31A987D2A9C52702437A5A929A44478172470F75DABDAB1C6B66772B0720E2B53CF0459384A6DB94A18B621AD271881B7DBAD8AE4C330965D6CD367B96B830256233113C03191186A05B3F4D90A349CC8816642A0A55DD3D95DF8CBC999C05A48E79282BC434C7AA7A08C3BAA8C4FA686C78F8A2F99D102F75023C3FA87188429817170348A40C1350EAC679BE5158B9CF5950D4871F9EC687621196D3B420F0B6360A3A721B2B29E4988F315A52253369340BF54CB70A6F569192FA55361EE3482F39F344B5E5217A624461B9B6FA830E17A7A45D0E59D2EECE64AADF692860235678DCC2B9818B3DF268AB12B07C94C627D2C5FB929D435CA2260A6AAED"); + private static final Map parametersMap = new HashMap() { { @@ -43,6 +49,68 @@ public class MLKEMTest } }; + private final SecureRandom RANDOM = new SecureRandom(); + + public void testKeys() + { + new MLKEMPublicKeyParameters(MLKEMParameters.ml_kem_512, okayKey); + + try + { + new MLKEMPublicKeyParameters(MLKEMParameters.ml_kem_512, tooLargeKey); + fail("no exception for invalid public key"); + } + catch (IllegalArgumentException e) + { + assertEquals("'encoding' has invalid length", e.getMessage()); + } + + try + { + new MLKEMPrivateKeyParameters(MLKEMParameters.ml_kem_512, faultyPrivateKey); + fail("no exception for invalid private key"); + } + catch (IllegalArgumentException e) + { + assertEquals("'encoding' fails hash check", e.getMessage()); + } + } + + public void testInputs() + throws Exception + { + MLKEMKeyPairGenerator kpGen = new MLKEMKeyPairGenerator(); + MLKEMKeyGenerationParameters genParam = new MLKEMKeyGenerationParameters(new SecureRandom(), MLKEMParameters.ml_kem_512); + + // + // Generate keys and test. + // + kpGen.init(genParam); + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + + MLKEMExtractor kEx = new MLKEMExtractor((MLKEMPrivateKeyParameters)kp.getPrivate()); + + try + { + kEx.extractSecret(new byte[2000]); + Assert.fail(); + } + catch (IllegalArgumentException e) + { + assertEquals("encapsulation wrong length", e.getMessage()); + } + + try + { + kEx.extractSecret(new byte[600]); + Assert.fail(); + } + catch (IllegalArgumentException e) + { + assertEquals("encapsulation wrong length", e.getMessage()); + } + } + public void testKeyGen() throws IOException { MLKEMParameters[] params = new MLKEMParameters[]{ @@ -224,7 +292,7 @@ public void testEncapDecap_encapsulation() throws IOException // PrivateKeyInfoFactory.createPrivateKeyInfo((MLKEMPrivateKeyParameters)privKey)); // KEM Enc - MLKEMGenerator generator = new MLKEMGenerator(new SecureRandom()); + MLKEMGenerator generator = new MLKEMGenerator(RANDOM); SecretWithEncapsulation secWenc = generator.internalGenerateEncapsulated(pubParams, m); byte[] generated_cipher_text = secWenc.getEncapsulation(); @@ -352,7 +420,7 @@ public void testEncapDecapCombinedVectorSet() throws IOException MLKEMPublicKeyParameters pubParams = (MLKEMPublicKeyParameters)PublicKeyFactory.createKey( SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo((MLKEMPublicKeyParameters)pubKey)); - MLKEMGenerator generator = new MLKEMGenerator(new SecureRandom()); + MLKEMGenerator generator = new MLKEMGenerator(RANDOM); SecretWithEncapsulation secWenc = generator.internalGenerateEncapsulated(pubParams, m); byte[] generated_cipher_text = secWenc.getEncapsulation(); byte[] secret = secWenc.getSecret(); @@ -431,14 +499,13 @@ public void testModulus() throws IOException public void testPrivInfoGeneration() throws IOException { - SecureRandom random = new SecureRandom(); PQCOtherInfoGenerator.PartyU partyU = new PQCOtherInfoGenerator.PartyU(MLKEMParameters.ml_kem_512, - new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), random); + new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), RANDOM); byte[] partA = partyU.getSuppPrivInfoPartA(); PQCOtherInfoGenerator.PartyV partyV = new PQCOtherInfoGenerator.PartyV(MLKEMParameters.ml_kem_512, - new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), random); + new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1), Hex.decode("beef"), Hex.decode("cafe"), RANDOM); byte[] partB = partyV.getSuppPrivInfoPartB(partA); @@ -456,7 +523,6 @@ public void testMLKEM() String expectedPubKey = "A04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21"; String expectedPrivKey = "8C8B3722A82E550565521611EBBC63079944C9B1ABB3B0020FF12F631891A9C468D3A67BF6271280DA58D03CB042B3A461441637F929C273469AD15311E910DE18CB9537BA1BE42E98BB59E498A13FD440D0E69EE832B45CD95C382177D67096A18C07F1781663651BDCAC90DEDA3DDD143485864181C91FA2080F6DAB3F86204CEB64A7B4446895C03987A031CB4B6D9E0462FDA829172B6C012C638B29B5CD75A2C930A5596A3181C33A22D574D30261196BC350738D4FD9183A763336243ACED99B3221C71D8866895C4E52C119BF3280DAF80A95E15209A795C4435FBB3570FDB8AA9BF9AEFD43B094B781D5A81136DAB88B8799696556FEC6AE14B0BB8BE4695E9A124C2AB8FF4AB1229B8AAA8C6F41A60C34C7B56182C55C2C685E737C6CA00A23FB8A68C1CD61F30D3993A1653C1675AC5F0901A7160A73966408B8876B715396CFA4903FC69D60491F8146808C97CD5C533E71017909E97B835B86FF847B42A696375435E006061CF7A479463272114A89EB3EAF2246F0F8C104A14986828E0AD20420C9B37EA23F5C514949E77AD9E9AD12290DD1215E11DA274457AC86B1CE6864B122677F3718AA31B02580E64317178D38F25F609BC6C55BC374A1BF78EA8ECC219B30B74CBB3272A599238C93985170048F176775FB19962AC3B135AA59DB104F7114DBC2C2D42949ADECA6A85B323EE2B2B23A77D9DB235979A8E2D67CF7D2136BBBA71F269574B38888E1541340C19284074F9B7C8CF37EB01384E6E3822EC4882DFBBEC4E6098EF2B2FC177A1F0BCB65A57FDAA89315461BEB7885FB68B3CD096EDA596AC0E61DD7A9C507BC6345E0827DFCC8A3AC2DCE51AD731AA0EB932A6D0983992347CBEB3CD0D9C9719797CC21CF0062B0AD94CAD734C63E6B5D859CBE19F0368245351BF464D7505569790D2BB724D8659A9FEB1C7C473DC4D061E29863A2714BAC42ADCD1A8372776556F7928A7A44E94B6A25322D03C0A1622A7FD261522B7358F085BDFB60758762CB901031901B5EECF4920C81020A9B1781BCB9DD19A9DFB66458E7757C52CEC75B4BA740A24099CB56BB60A76B6901AA3E0169C9E83496D73C4C99435A28D613E97A1177F58B6CC595D3B2331E9CA7B57B74DC2C5277D26F2FE19240A55C35D6CFCA26C73E9A2D7C980D97960AE1A04698C16B398A5F20C35A0914145CE1674B71ABC6066A909A3E4B911E69D5A849430361F731B07246A6329B52361904225082D0AAC5B21D6B34862481A890C3C360766F04263603A6B73E802B1F70B2EB00046836B8F493BF10B90B8737C6C548449B294C47253BE26CA72336A632063AD3D0B48C8B0F4A34447EF13B764020DE739EB79ABA20E2BE1951825F293BEDD1089FCB0A91F560C8E17CDF52541DC2B81F972A7375B201F10C08D9B5BC8B95100054A3D0AAFF89BD08D6A0E7F2115A435231290460C9AD435A3B3CF35E52091EDD1890047BCC0AABB1ACEBC75F4A32BC1451ACC4969940788E89412188946C9143C5046BD1B458DF617C5DF533B052CD6038B7754034A23C2F7720134C7B4EACE01FAC0A2853A9285847ABBD06A3343A778AC6062E458BC5E61ECE1C0DE0206E6FE8A84034A7C5F1B005FB0A584051D3229B86C909AC5647B3D75569E05A88279D80E5C30F574DC327512C6BBE8101239EC62861F4BE67B05B9CDA9C545C13E7EB53CFF260AD9870199C21F8C63D64F0458A7141285023FEB829290872389644B0C3B73AC2C8E121A29BB1C43C19A233D56BED82740EB021C97B8EBBA40FF328B541760FCC372B52D3BC4FCBC06F424EAF253804D4CB46F41FF254C0C5BA483B44A87C219654555EC7C163C79B9CB760A2AD9BB722B93E0C28BD4B1685949C496EAB1AFF90919E3761B346838ABB2F01A91E554375AFDAAAF3826E6DB79FE7353A7A578A7C0598CE28B6D9915214236BBFFA6D45B6376A07924A39A7BE818286715C8A3C110CD76C02E0417AF138BDB95C3CCA798AC809ED69CFB672B6FDDC24D89C06A6558814AB0C21C62B2F84C0E3E0803DB337A4E0C7127A6B4C8C08B1D1A76BF07EB6E5B5BB47A16C74BC548375FB29CD789A5CFF91BDBD071859F4846E355BB0D29484E264DFF36C9177A7ACA78908879695CA87F25436BC12630724BB22F0CB64897FE5C41195280DA04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21D2E574DFD8CD0AE893AA7E125B44B924F45223EC09F2AD1141EA93A68050DBF699E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7"; - SecureRandom random = new SecureRandom(); MLKEMKeyPairGenerator keyGen = new MLKEMKeyPairGenerator(); keyGen.init(new MLKEMKeyGenerationParameters(new FixedSecureRandom(Arrays.concatenate(d, z)), MLKEMParameters.ml_kem_1024)); @@ -466,7 +532,7 @@ public void testMLKEM() assertTrue(Arrays.areEqual(Hex.decode(expectedPrivKey), ((MLKEMPrivateKeyParameters)keyPair.getPrivate()).getEncoded())); - MLKEMGenerator kemGen = new MLKEMGenerator(random); + MLKEMGenerator kemGen = new MLKEMGenerator(RANDOM); byte[] message = Hex.decode("59C5154C04AE43AAFF32700F081700389D54BEC4C37C088B1C53F66212B12C72"); @@ -511,16 +577,15 @@ public void testParameters() public void testMLKEMRandom() { - SecureRandom random = new SecureRandom(); MLKEMKeyPairGenerator keyGen = new MLKEMKeyPairGenerator(); - keyGen.init(new MLKEMKeyGenerationParameters(random, MLKEMParameters.ml_kem_1024)); + keyGen.init(new MLKEMKeyGenerationParameters(RANDOM, MLKEMParameters.ml_kem_1024)); for (int i = 0; i != 1000; i++) { AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair(); - MLKEMGenerator kemGen = new MLKEMGenerator(random); + MLKEMGenerator kemGen = new MLKEMGenerator(RANDOM); SecretWithEncapsulation secretEncap = kemGen.generateEncapsulated(keyPair.getPublic()); @@ -531,4 +596,48 @@ public void testMLKEMRandom() assertTrue(Arrays.areEqual(secretEncap.getSecret(), decryptedSharedSecret)); } } + + public void testWithPreferredFormat() + { + MLKEMParameters[] parameters = new MLKEMParameters[]{ + MLKEMParameters.ml_kem_512, + MLKEMParameters.ml_kem_768, + MLKEMParameters.ml_kem_1024, + }; + + for (int i = 0; i < parameters.length; ++i) + { + MLKEMKeyPairGenerator kpg = new MLKEMKeyPairGenerator(); + kpg.init(new MLKEMKeyGenerationParameters(RANDOM, parameters[i])); + + AsymmetricCipherKeyPair kp = kpg.generateKeyPair(); + MLKEMPrivateKeyParameters privateKey = (MLKEMPrivateKeyParameters)kp.getPrivate(); + + implWithPreferredFormat(privateKey, MLKEMPrivateKeyParameters.SEED_ONLY); + implWithPreferredFormat(privateKey, MLKEMPrivateKeyParameters.EXPANDED_KEY); + implWithPreferredFormat(privateKey, MLKEMPrivateKeyParameters.BOTH); + } + } + + private static void implWithPreferredFormat(MLKEMPrivateKeyParameters privateKey, int format) + { + int originalFormat = privateKey.getPreferredFormat(); + byte[] originalSeed = privateKey.getSeed(); + byte[] originalEncoding = privateKey.getEncoded(); + + MLKEMPrivateKeyParameters updatedPrivateKey = privateKey.withPreferredFormat(format); + + int updatedFormat = updatedPrivateKey.getPreferredFormat(); + byte[] updatedSeed = updatedPrivateKey.getSeed(); + byte[] updatedEncoding = updatedPrivateKey.getEncoded(); + + assertEquals(format, updatedFormat); + assertTrue(Arrays.areEqual(originalSeed, updatedSeed)); + assertTrue(Arrays.areEqual(originalEncoding, updatedEncoding)); + + if (format == originalFormat) + { + assertSame(privateKey, updatedPrivateKey); + } + } } diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/MayoTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/MayoTest.java index e275ecf2de..5dee4da12a 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/MayoTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/MayoTest.java @@ -46,7 +46,7 @@ public void testTestVectors() throws Exception { long start = System.currentTimeMillis(); - TestUtils.testTestVector(false, true, false, "pqc/crypto/mayo", files, new TestUtils.KeyGenerationOperation() + TestUtils.testTestVector(false, true, false, "pqc/crypto/mayo", files, new TestUtils.SignerOperation() { @Override public SecureRandom getSecureRandom(byte[] seed) diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUPlusTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUPlusTest.java new file mode 100644 index 0000000000..c2037f7665 --- /dev/null +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/NTRUPlusTest.java @@ -0,0 +1,101 @@ +package org.bouncycastle.pqc.crypto.test; + +import java.security.SecureRandom; + +import junit.framework.TestCase; +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.bouncycastle.crypto.EncapsulatedSecretExtractor; +import org.bouncycastle.crypto.EncapsulatedSecretGenerator; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKEMExtractor; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKEMGenerator; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKeyPairGenerator; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPublicKeyParameters; + +public class NTRUPlusTest + extends TestCase +{ + public static void main(String[] args) + throws Exception + { + NTRUPlusTest test = new NTRUPlusTest(); + test.testTestVectors(); + //test.testKeyGen(); + } + + private static final NTRUPlusParameters[] PARAMETER_SETS = new NTRUPlusParameters[] + { + NTRUPlusParameters.ntruplus_kem_768, + NTRUPlusParameters.ntruplus_kem_864, + NTRUPlusParameters.ntruplus_kem_1152, + }; + + private static final String[] files = new String[]{ + "PQCkemKAT_2336.rsp", + "PQCkemKAT_2624.rsp", + "PQCkemKAT_3488.rsp", + }; + + + public void testTestVectors() + throws Exception + { + long start = System.currentTimeMillis(); + TestUtils.testTestVector(false, true, "pqc/crypto/ntruplus", files, new TestUtils.KeyEncapsulationOperation() + { + int sessionKeySize = 0; + + @Override + public SecureRandom getSecureRandom(byte[] seed) + { + return new NISTSecureRandom(seed, null); + } + + @Override + public AsymmetricCipherKeyPairGenerator getAsymmetricCipherKeyPairGenerator(int fileIndex, SecureRandom random) + { + NTRUPlusParameters parameters = PARAMETER_SETS[fileIndex]; + sessionKeySize = parameters.getSsBytes() * 8; + NTRUPlusKeyPairGenerator kpGen = new NTRUPlusKeyPairGenerator(); + kpGen.init(new NTRUPlusKeyGenerationParameters(random, parameters)); + return kpGen; + } + + @Override + public byte[] getPublicKeyEncoded(AsymmetricKeyParameter pubParams) + { + return ((NTRUPlusPublicKeyParameters)pubParams).getEncoded(); + } + + @Override + public byte[] getPrivateKeyEncoded(AsymmetricKeyParameter privParams) + { + return ((NTRUPlusPrivateKeyParameters)privParams).getEncoded(); + } + + @Override + public EncapsulatedSecretGenerator getKEMGenerator(SecureRandom random) + { + return new NTRUPlusKEMGenerator(random); + } + + @Override + public EncapsulatedSecretExtractor getKEMExtractor(AsymmetricKeyParameter privParams) + { + return new NTRUPlusKEMExtractor((NTRUPlusPrivateKeyParameters)privParams); + } + + @Override + public int getSessionKeySize() + { + return 0; + } + + }); + long end = System.currentTimeMillis(); + System.out.println("time cost: " + (end - start) + "\n"); + } +} diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SnovaTest.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SnovaTest.java index 2800c307b5..54ccbe264f 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/SnovaTest.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/SnovaTest.java @@ -126,7 +126,7 @@ public void testTestVectors() throws Exception { long start = System.currentTimeMillis(); - TestUtils.testTestVector(true, true, false, "pqc/crypto/snova", files, new TestUtils.KeyGenerationOperation() + TestUtils.testTestVector(true, true, false, "pqc/crypto/snova", files, new TestUtils.SignerOperation() { @Override public SecureRandom getSecureRandom(byte[] seed) diff --git a/core/src/test/java/org/bouncycastle/pqc/crypto/test/TestUtils.java b/core/src/test/java/org/bouncycastle/pqc/crypto/test/TestUtils.java index 32072717f1..1fdcac3574 100644 --- a/core/src/test/java/org/bouncycastle/pqc/crypto/test/TestUtils.java +++ b/core/src/test/java/org/bouncycastle/pqc/crypto/test/TestUtils.java @@ -7,10 +7,12 @@ import java.util.HashMap; import junit.framework.Assert; - import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.EncapsulatedSecretExtractor; +import org.bouncycastle.crypto.EncapsulatedSecretGenerator; +import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.Signer; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; @@ -30,7 +32,7 @@ static boolean parseBoolean(String value) return "true".equalsIgnoreCase(value); } - public interface KeyGenerationOperation + public interface SignerOperation { SecureRandom getSecureRandom(byte[] seed); @@ -45,7 +47,24 @@ public interface KeyGenerationOperation MessageSigner getMessageSigner(); } - public static void testTestVector(boolean sampleOnly, boolean enableFactory, boolean isSigner, String homeDir, String[] files, KeyGenerationOperation operation) + public interface KeyEncapsulationOperation + { + SecureRandom getSecureRandom(byte[] seed); + + AsymmetricCipherKeyPairGenerator getAsymmetricCipherKeyPairGenerator(int fileIndex, SecureRandom random); + + byte[] getPublicKeyEncoded(AsymmetricKeyParameter pubParams); + + byte[] getPrivateKeyEncoded(AsymmetricKeyParameter privParams); + + EncapsulatedSecretGenerator getKEMGenerator(SecureRandom random); + + EncapsulatedSecretExtractor getKEMExtractor(AsymmetricKeyParameter privParams); + + int getSessionKeySize(); + } + + public static void testTestVector(boolean sampleOnly, boolean enableFactory, boolean isSigner, String homeDir, String[] files, SignerOperation operation) throws Exception { for (int fileIndex = 0; fileIndex != files.length; fileIndex++) @@ -153,4 +172,97 @@ public static void testTestVector(boolean sampleOnly, boolean enableFactory, boo } } } + + public static void testTestVector(boolean sampleOnly, boolean enableFactory, String homeDir, String[] files, KeyEncapsulationOperation operation) + throws Exception + { + for (int fileIndex = 0; fileIndex < files.length; fileIndex++) + { + String name = files[fileIndex]; + //System.out.println(files[fileIndex]); + InputStream src = TestResourceFinder.findTestResource(homeDir, name); + BufferedReader bin = new BufferedReader(new InputStreamReader(src)); + + String line = null; + HashMap buf = new HashMap(); + TestSampler sampler = sampleOnly ? new TestSampler() : null; + while ((line = bin.readLine()) != null) + { + line = line.trim(); + + if (line.startsWith("#")) + { + continue; + } + if (line.isEmpty()) + { + if (!buf.isEmpty()) + { + String count = (String)buf.get("count"); + if (sampler != null && sampler.skipTest(count)) + { + continue; + } + System.out.println("test case: " + count); + + byte[] seed = Hex.decode((String)buf.get("seed")); // seed for bike secure random + byte[] pk = Hex.decode((String)buf.get("pk")); // public key + byte[] sk = Hex.decode((String)buf.get("sk")); // private key + byte[] ct = Hex.decode((String)buf.get("ct")); // ciphertext + byte[] ss = Hex.decode((String)buf.get("ss")); // session key + + SecureRandom random = operation.getSecureRandom(seed); + + AsymmetricCipherKeyPairGenerator kpGen = operation.getAsymmetricCipherKeyPairGenerator(fileIndex, random); + + // + // Generate keys and test. + // + AsymmetricCipherKeyPair kp = kpGen.generateKeyPair(); + AsymmetricKeyParameter pubParams; + AsymmetricKeyParameter privParams; + if (enableFactory) + { + pubParams = PublicKeyFactory.createKey( + SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(kp.getPublic())); + privParams = PrivateKeyFactory.createKey( + PrivateKeyInfoFactory.createPrivateKeyInfo(kp.getPrivate())); + } + else + { + pubParams = kp.getPublic(); + privParams = kp.getPrivate(); + } + + Assert.assertTrue(name + " " + count + ": public key", Arrays.areEqual(pk, operation.getPublicKeyEncoded(pubParams))); + Assert.assertTrue(name + " " + count + ": secret key", Arrays.areEqual(sk, operation.getPrivateKeyEncoded(privParams))); + + // KEM Encapsulation + EncapsulatedSecretGenerator kemGenerator = operation.getKEMGenerator(random); + SecretWithEncapsulation secretWithEnc = kemGenerator.generateEncapsulated(pubParams); + byte[] secret = secretWithEnc.getSecret(); + byte[] c = secretWithEnc.getEncapsulation(); + + Assert.assertTrue(name + " " + count + ": ciphertext", Arrays.areEqual(c, ct)); + Assert.assertTrue(name + " " + count + ": kem_dec ss", Arrays.areEqual(secret, 0, secret.length, ss, 0, secret.length)); + + // KEM Decapsulation + EncapsulatedSecretExtractor kemExtractor = operation.getKEMExtractor(privParams); + byte[] dec_key = kemExtractor.extractSecret(c); + + //Assert.assertTrue(operation.getSessionKeySize() == secret.length * 8); + Assert.assertTrue(name + " " + count + ": kem_dec key", Arrays.areEqual(dec_key, secret)); + } + buf.clear(); + continue; + } + int a = line.indexOf("="); + if (a > -1) + { + buf.put(line.substring(0, a).trim(), line.substring(a + 1).trim()); + } + } + // System.out.println("Testing successful!"); + } + } } diff --git a/core/src/test/java/org/bouncycastle/util/utiltest/AllTests.java b/core/src/test/java/org/bouncycastle/util/utiltest/AllTests.java index f4d21358c2..19ff5734fc 100644 --- a/core/src/test/java/org/bouncycastle/util/utiltest/AllTests.java +++ b/core/src/test/java/org/bouncycastle/util/utiltest/AllTests.java @@ -19,6 +19,7 @@ public static Test suite() suite.addTestSuite(IPTest.class); suite.addTestSuite(BigIntegersTest.class); suite.addTestSuite(ArraysTest.class); + suite.addTestSuite(StringsTest.class); return new BCTestSetup(suite); } diff --git a/core/src/test/java/org/bouncycastle/util/utiltest/StringsTest.java b/core/src/test/java/org/bouncycastle/util/utiltest/StringsTest.java new file mode 100644 index 0000000000..4e1ba3f7b8 --- /dev/null +++ b/core/src/test/java/org/bouncycastle/util/utiltest/StringsTest.java @@ -0,0 +1,67 @@ +package org.bouncycastle.util.utiltest; + +import junit.framework.TestCase; +import org.bouncycastle.util.Strings; + +public class StringsTest + extends TestCase +{ + public void testSplitWithLeadingDelimiter() + { + String[] parts = Strings.split(".permitted", '.'); + assertEquals(2, parts.length); + assertEquals("", parts[0]); + assertEquals("permitted", parts[1]); + } + + public void testSplitDomainWithLeadingDot() + { + String[] parts = Strings.split(".example.domain.com", '.'); + assertEquals(4, parts.length); + assertEquals("", parts[0]); + assertEquals("example", parts[1]); + assertEquals("domain", parts[2]); + assertEquals("com", parts[3]); + } + + public void testSplitNormalDomain() + { + String[] parts = Strings.split("example.domain.com", '.'); + assertEquals(3, parts.length); + assertEquals("example", parts[0]); + assertEquals("domain", parts[1]); + assertEquals("com", parts[2]); + } + + public void testSplitNoDelimiter() + { + String[] parts = Strings.split("nodots", '.'); + assertEquals(1, parts.length); + assertEquals("nodots", parts[0]); + } + + public void testSplitTrailingDelimiter() + { + String[] parts = Strings.split("trailing.", '.'); + assertEquals(2, parts.length); + assertEquals("trailing", parts[0]); + assertEquals("", parts[1]); + } + + public void testSplitOnlyDelimiter() + { + String[] parts = Strings.split(".", '.'); + assertEquals(2, parts.length); + assertEquals("", parts[0]); + assertEquals("", parts[1]); + } + + public void testSplitConsecutiveDelimiters() + { + String[] parts = Strings.split("a..b", '.'); + assertEquals(3, parts.length); + assertEquals("a", parts[0]); + assertEquals("", parts[1]); + assertEquals("b", parts[2]); + } +} diff --git a/docs/releasenotes.html b/docs/releasenotes.html index 3e925c9546..f749606926 100644 --- a/docs/releasenotes.html +++ b/docs/releasenotes.html @@ -24,6 +24,14 @@

    2.0 Release History

    2.1.2 Defects Fixed

    • Random numbers being generated for DSTU4145 signature calculations were 1 bit shorter than they could be. The code has been corrected to allow the generated numbers to occupy the full numeric range available.
    • +
    • CompositePublic/PrivateKey builders had an issue identifying brainpool and EdDSA curves from the algorithm names due to an error in the OID mapping table. This has been fixed.
    • +
    +

    2.1.3 Additional Features and Functionality

    +
      +
    +

    2.1.4 Additional Notes

    +
      +
    • DSA was recently deprecated by NIST and several users have requested that we move to an RSA signing certificate for provider signing instead of our current DSA one. We are grateful to report that Oracle have been very supportive of this and issued us a second RSA certificate based on a new RSA key for signing providers. Providers signed with the previous DSA key will continue to work as before.

    2.2.1 Version

    diff --git a/gradle.properties b/gradle.properties index 23eab4d0a5..455d1be300 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs=-Xmx2g -version=1.83 -maxVersion=1.84 +version=1.84-SNAPSHOT +maxVersion=1.85 org.gradle.java.installations.auto-detect=false org.gradle.java.installations.auto-download=false org.gradle.java.installations.fromEnv=BC_JDK8,BC_JDK11,BC_JDK17,BC_JDK21,BC_JDK25 diff --git a/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java b/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java index f4433be57d..8328209308 100644 --- a/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java +++ b/mls/src/main/java/org/bouncycastle/mls/TranscriptHash.java @@ -42,7 +42,7 @@ public TranscriptHash(MlsCipherSuite suite, byte[] confirmed, byte[] interim) this.interim = interim; } - static public TranscriptHash fromConfirmationTag(MlsCipherSuite suite, byte[] confirmed, byte[] confirmationTag) + public static TranscriptHash fromConfirmationTag(MlsCipherSuite suite, byte[] confirmed, byte[] confirmationTag) throws IOException { TranscriptHash out = new TranscriptHash(suite, confirmed.clone(), new byte[0]); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java b/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java index f3b7a98bd7..789dec72b1 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Capabilities.java @@ -10,9 +10,9 @@ public class Capabilities implements MLSInputStream.Readable, MLSOutputStream.Writable { - static private final Short[] DEFAULT_SUPPORTED_VERSIONS = {ProtocolVersion.mls10.value}; - static private final short[] DEFAULT_SUPPORTED_CIPHERSUITES = MlsCipherSuite.ALL_SUPPORTED_SUITES; - static private final Short[] DEFAULT_SUPPORTED_CREDENTIALS = {CredentialType.basic.value, CredentialType.x509.value}; + private static final Short[] DEFAULT_SUPPORTED_VERSIONS = {ProtocolVersion.mls10.value}; + private static final short[] DEFAULT_SUPPORTED_CIPHERSUITES = MlsCipherSuite.ALL_SUPPORTED_SUITES; + private static final Short[] DEFAULT_SUPPORTED_CREDENTIALS = {CredentialType.basic.value, CredentialType.x509.value}; List versions; List cipherSuites; List extensions; diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java b/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java index 8cb2b985c5..536c6ab908 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Credential.java @@ -22,7 +22,7 @@ public byte[] getIdentity() return identity; } - static public Credential forBasic(byte[] identity) + public static Credential forBasic(byte[] identity) { return new Credential(CredentialType.basic, identity, new ArrayList()); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java b/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java index 3a58e85189..6ca37a2c52 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/Extension.java @@ -32,7 +32,7 @@ public Extension(int extensionType, byte[] extension_data) this.extension_data = extension_data; } - static public Extension externalSender(List list) + public static Extension externalSender(List list) throws IOException { MLSOutputStream stream = new MLSOutputStream(); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java b/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java index 5591c74d2a..ab7271660e 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/MLSMessage.java @@ -23,7 +23,7 @@ public MLSMessage(WireFormat wireFormat) this.wireFormat = wireFormat; } - static public MLSMessage externalProposal(MlsCipherSuite suite, byte[] groupID, long epoch, Proposal proposal, int signerIndex, byte[] sigSk) + public static MLSMessage externalProposal(MlsCipherSuite suite, byte[] groupID, long epoch, Proposal proposal, int signerIndex, byte[] sigSk) throws Exception { switch (proposal.getProposalType()) @@ -59,7 +59,7 @@ static public MLSMessage externalProposal(MlsCipherSuite suite, byte[] groupID, return message; } - static public MLSMessage keyPackage(KeyPackage keyPackage) + public static MLSMessage keyPackage(KeyPackage keyPackage) { MLSMessage message = new MLSMessage(WireFormat.mls_key_package); message.version = ProtocolVersion.mls10; diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java b/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java index 49203cd6e3..15c36203c0 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/PrivateMessage.java @@ -42,7 +42,7 @@ public PrivateMessage(byte[] group_id, long epoch, ContentType content_type, byt ciphertext = stream.readOpaque(); } - static public PrivateMessage protect(AuthenticatedContent auth, MlsCipherSuite suite, GroupKeySet keys, byte[] senderDataSecretBytes, int paddingSize) + public static PrivateMessage protect(AuthenticatedContent auth, MlsCipherSuite suite, GroupKeySet keys, byte[] senderDataSecretBytes, int paddingSize) throws IOException, IllegalAccessException, InvalidCipherTextException { // Get KeyGeneration from the secret tree @@ -203,7 +203,7 @@ private void deserializeContentPt(byte[] contentPt, FramedContent content, Frame //TODO: read padding? } - static private byte[] serializeContentPt(FramedContent content, FramedContentAuthData auth, int paddingSize) + private static byte[] serializeContentPt(FramedContent content, FramedContentAuthData auth, int paddingSize) throws IOException { MLSOutputStream stream = new MLSOutputStream(); diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java index 994e75ccac..c376f045e8 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/ProposalOrRef.java @@ -26,12 +26,12 @@ public byte[] getReference() } - static public ProposalOrRef forRef(byte[] ref) + public static ProposalOrRef forRef(byte[] ref) { return new ProposalOrRef(ProposalOrRefType.REFERENCE, null, ref); } - static public ProposalOrRef forProposal(Proposal proposal) + public static ProposalOrRef forProposal(Proposal proposal) { return new ProposalOrRef(ProposalOrRefType.PROPOSAL, proposal, null); } diff --git a/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java b/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java index cb8ed08ec4..6fe9780af2 100644 --- a/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java +++ b/mls/src/main/java/org/bouncycastle/mls/codec/PublicMessage.java @@ -74,7 +74,7 @@ public PublicMessage(FramedContent content, FramedContentAuthData auth, byte[] m } } - static public PublicMessage protect(AuthenticatedContent authContent, MlsCipherSuite suite, + public static PublicMessage protect(AuthenticatedContent authContent, MlsCipherSuite suite, byte[] membershipKeyBytes, byte[] groupContextBytes) throws IOException { diff --git a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java index 85fff81b4c..f549ede7ed 100644 --- a/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java +++ b/mls/src/main/java/org/bouncycastle/mls/crypto/MlsCipherSuite.java @@ -107,7 +107,7 @@ public MlsCipherSuite(short id, MlsSigner signer, MlsKdf kdf, MlsAead aead, HPKE this.hpke = hpke; } - static public MlsCipherSuite getSuite(short id) + public static MlsCipherSuite getSuite(short id) throws Exception { switch (id) diff --git a/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java b/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java index bedaed9e4f..04f3fbc08e 100644 --- a/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java +++ b/mls/src/main/java/org/bouncycastle/mls/protocol/Group.java @@ -193,7 +193,7 @@ public TombstoneWithMessage(Group group, Proposal.ReInit reinit, MLSMessage mess public static final short RESTART_COMMIT_PARAMS = 2; public static final short REINIT_COMMIT_PARAMS = 3; - static public class CommitParameters + public static class CommitParameters { short paramID; // External diff --git a/pg/src/main/java/org/bouncycastle/openpgp/PGPSessionKey.java b/pg/src/main/java/org/bouncycastle/openpgp/PGPSessionKey.java index d713051d9d..c597d06687 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/PGPSessionKey.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/PGPSessionKey.java @@ -3,10 +3,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; public class PGPSessionKey { + private static final Pattern ASCII_ENCODING_PATTERN = Pattern.compile("(\\d{1,3}):([0-9A-Fa-f]+)"); + private final int algorithm; private final byte[] sessionKey; @@ -23,22 +26,20 @@ public int getAlgorithm() public byte[] getKey() { - byte[] copy = new byte[sessionKey.length]; - System.arraycopy(sessionKey, 0, copy, 0, sessionKey.length); - return copy; + return Arrays.clone(sessionKey); } - @SuppressWarnings("ArrayToString") public String toString() { - // mote: we only print the reference to sessionKey to prevent accidental disclosure of the actual key value. - return algorithm + ":" + sessionKey; + // NOTE: Avoid disclosing the sessionKey value. + String sessionKeyHashCode = Integer.toHexString(System.identityHashCode(sessionKey)); + + return algorithm + ":" + sessionKey.getClass().getName() + "@" + sessionKeyHashCode; } public static PGPSessionKey fromAsciiRepresentation(String ascii) { - Pattern pattern = Pattern.compile("(\\d{1,3}):([0-9A-Fa-f]+)"); - Matcher matcher = pattern.matcher(ascii); + Matcher matcher = ASCII_ENCODING_PATTERN.matcher(ascii); if (!matcher.matches()) { throw new IllegalArgumentException("Provided ascii encoding does not match expected format :"); diff --git a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java index 0ebe601a36..5c77c49eb2 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JceAEADCipherUtil.java @@ -76,7 +76,7 @@ public ASN1Primitive toASN1Primitive() if (icvLen != 12) { - v.add(new ASN1Integer(icvLen)); + v.add(ASN1Integer.valueOf(icvLen)); } return new DERSequence(v); diff --git a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java index eeceef671d..2f73b433ea 100644 --- a/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java +++ b/pg/src/test/java/org/bouncycastle/openpgp/test/PGPSessionKeyTest.java @@ -88,9 +88,9 @@ public class PGPSessionKeyTest public static void main(String[] args) throws Exception { - PGPSessionKeyTest test = new PGPSessionKeyTest(); Security.addProvider(new BouncyCastleProvider()); - test.performTest(); + + runTest(new PGPSessionKeyTest()); } public String getName() diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java index a873d6572b..a1137bac62 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataGenerator.java @@ -4,8 +4,11 @@ import java.io.IOException; import java.io.OutputStream; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.AuthEnvelopedData; @@ -55,16 +58,18 @@ private CMSAuthEnvelopedData doGenerate( throw new CMSException("unable to process authenticated content: " + e.getMessage(), e); } - byte[] encryptedContent = bOut.toByteArray(); - byte[] mac = contentEncryptor.getMAC(); + ASN1OctetString encryptedContent = new BEROctetString(bOut.toByteArray()); + ASN1OctetString mac = new DEROctetString(contentEncryptor.getMAC()); - EncryptedContentInfo eci = CMSUtils.getEncryptedContentInfo(content, contentEncryptor, encryptedContent); + EncryptedContentInfo encryptedContentInfo = CMSUtils.getEncryptedContentInfo(content, contentEncryptor, + encryptedContent); ASN1Set unprotectedAttrSet = CMSUtils.getAttrDLSet(unauthAttrsGenerator); - ContentInfo contentInfo = new ContentInfo( - CMSObjectIdentifiers.authEnvelopedData, - new AuthEnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, authenticatedAttrSet, new DEROctetString(mac), unprotectedAttrSet)); + ASN1Encodable authEnvelopedData = new AuthEnvelopedData(originatorInfo, new DERSet(recipientInfos), + encryptedContentInfo, authenticatedAttrSet, mac, unprotectedAttrSet); + + ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.authEnvelopedData, authEnvelopedData); return new CMSAuthEnvelopedData(contentInfo); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java index 9271db7a5c..7de49e3daf 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthEnvelopedDataStreamGenerator.java @@ -11,7 +11,6 @@ import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.OutputAEADEncryptor; /** @@ -63,36 +62,25 @@ protected OutputStream open( OutputAEADEncryptor encryptor) throws IOException { - // // ContentInfo - // - BERSequenceGenerator cGen = new BERSequenceGenerator(out); + BERSequenceGenerator ciGen = new BERSequenceGenerator(out); + ciGen.addObject(CMSObjectIdentifiers.authEnvelopedData); - cGen.addObject(CMSObjectIdentifiers.authEnvelopedData); + // AuthEnvelopedData + BERSequenceGenerator aedGen = new BERSequenceGenerator(ciGen.getRawOutputStream(), 0, true); + aedGen.addObject(ASN1Integer.ZERO); + CMSUtils.addOriginatorInfoToGenerator(aedGen, originatorInfo); + CMSUtils.addRecipientInfosToGenerator(recipientInfos, aedGen, _berEncodeRecipientSet); - // - // Encrypted Data - // - BERSequenceGenerator authEnvGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); + // EncryptedContentInfo + BERSequenceGenerator eciGen = new BERSequenceGenerator(aedGen.getRawOutputStream()); + eciGen.addObject(dataType); + eciGen.addObject(encryptor.getAlgorithmIdentifier()); - authEnvGen.addObject(new ASN1Integer(0)); + // encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL (EncryptedContent ::= OCTET STRING) + OutputStream ecStream = CMSUtils.createBEROctetOutputStream(eciGen.getRawOutputStream(), 0, false, _bufferSize); - CMSUtils.addOriginatorInfoToGenerator(authEnvGen, originatorInfo); - - CMSUtils.addRecipientInfosToGenerator(recipientInfos, authEnvGen, _berEncodeRecipientSet); - - BERSequenceGenerator eiGen = new BERSequenceGenerator(authEnvGen.getRawOutputStream()); - - eiGen.addObject(dataType); - - AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); - - eiGen.getRawOutputStream().write(encAlgId.getEncoded()); - - OutputStream octetStream = CMSUtils.createBEROctetOutputStream( - eiGen.getRawOutputStream(), 0, true, _bufferSize); - - return new CMSAuthEnvelopedDataOutputStream(encryptor, octetStream, cGen, authEnvGen, eiGen); + return new CMSAuthEnvelopedDataOutputStream(encryptor, ecStream, ciGen, aedGen, eciGen); } protected OutputStream open( diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java index a31c0d084b..972b84a43c 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSAuthenticatedDataStreamGenerator.java @@ -136,52 +136,40 @@ public OutputStream open( { ASN1EncodableVector recipientInfos = CMSUtils.getRecipentInfos(macCalculator.getKey(), recipientInfoGenerators); - // // ContentInfo - // BERSequenceGenerator cGen = new BERSequenceGenerator(out); - cGen.addObject(CMSObjectIdentifiers.authenticatedData); - // - // Authenticated Data - // + // AuthenticatedData BERSequenceGenerator authGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); - - authGen.addObject(new ASN1Integer(AuthenticatedData.calculateVersion(originatorInfo))); - + authGen.addObject(ASN1Integer.valueOf(AuthenticatedData.calculateVersion(originatorInfo))); CMSUtils.addOriginatorInfoToGenerator(authGen, originatorInfo); - CMSUtils.addRecipientInfosToGenerator(recipientInfos, authGen, berEncodeRecipientSet); - - AlgorithmIdentifier macAlgId = macCalculator.getAlgorithmIdentifier(); - - authGen.getRawOutputStream().write(macAlgId.getEncoded()); + authGen.addObject(macCalculator.getAlgorithmIdentifier()); if (digestCalculator != null) { authGen.addObject(new DERTaggedObject(false, 1, digestCalculator.getAlgorithmIdentifier())); } - - BERSequenceGenerator eiGen = new BERSequenceGenerator(authGen.getRawOutputStream()); - eiGen.addObject(dataType); + // EncapsulatedContentInfo + BERSequenceGenerator eciGen = new BERSequenceGenerator(authGen.getRawOutputStream()); + eciGen.addObject(dataType); - OutputStream octetStream = CMSUtils.createBEROctetOutputStream( - eiGen.getRawOutputStream(), 0, true, bufferSize); + // eContent [0] EXPLICIT OCTET STRING OPTIONAL + OutputStream ecStream = CMSUtils.createBEROctetOutputStream(eciGen.getRawOutputStream(), 0, true, bufferSize); OutputStream mOut; - if (digestCalculator != null) { - mOut = new TeeOutputStream(octetStream, digestCalculator.getOutputStream()); + mOut = new TeeOutputStream(ecStream, digestCalculator.getOutputStream()); } else { - mOut = new TeeOutputStream(octetStream, macCalculator.getOutputStream()); + mOut = new TeeOutputStream(ecStream, macCalculator.getOutputStream()); } - return new CmsAuthenticatedDataOutputStream(macCalculator, digestCalculator, dataType, mOut, cGen, authGen, eiGen); + return new CmsAuthenticatedDataOutputStream(macCalculator, digestCalculator, dataType, mOut, cGen, authGen, eciGen); } catch (IOException e) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java index 02b5129113..17b96c42b9 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSCompressedDataStreamGenerator.java @@ -79,34 +79,23 @@ public OutputStream open( OutputCompressor compressor) throws IOException { + // ContentInfo BERSequenceGenerator sGen = new BERSequenceGenerator(out); - sGen.addObject(CMSObjectIdentifiers.compressedData); - // - // Compressed Data - // + // CompressedData BERSequenceGenerator cGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); - - cGen.addObject(new ASN1Integer(0)); - - // - // AlgorithmIdentifier - // + cGen.addObject(ASN1Integer.ZERO); cGen.addObject(compressor.getAlgorithmIdentifier()); - // - // Encapsulated ContentInfo - // - BERSequenceGenerator eiGen = new BERSequenceGenerator(cGen.getRawOutputStream()); - - eiGen.addObject(contentOID); + // EncapsulatedContentInfo + BERSequenceGenerator eciGen = new BERSequenceGenerator(cGen.getRawOutputStream()); + eciGen.addObject(contentOID); - OutputStream octetStream = CMSUtils.createBEROctetOutputStream( - eiGen.getRawOutputStream(), 0, true, _bufferSize); + // eContent [0] EXPLICIT OCTET STRING OPTIONAL + OutputStream ecStream = CMSUtils.createBEROctetOutputStream(eciGen.getRawOutputStream(), 0, true, _bufferSize); - return new CmsCompressedOutputStream( - compressor.getOutputStream(octetStream), sGen, cGen, eiGen); + return new CmsCompressedOutputStream(compressor.getOutputStream(ecStream), sGen, cGen, eciGen); } private static class CmsCompressedOutputStream diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java index dac06a1732..fb069122ed 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEncryptedDataGenerator.java @@ -11,7 +11,6 @@ import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EncryptedData; -import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.operator.OutputEncryptor; /** @@ -46,9 +45,6 @@ private CMSEncryptedData doGenerate( OutputEncryptor contentEncryptor) throws CMSException { - AlgorithmIdentifier encAlgId; - ASN1OctetString encContent; - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); try @@ -64,22 +60,16 @@ private CMSEncryptedData doGenerate( throw new CMSException(""); } - byte[] encryptedContent = bOut.toByteArray(); - - encAlgId = contentEncryptor.getAlgorithmIdentifier(); + ASN1OctetString encryptedContent = new BEROctetString(bOut.toByteArray()); - encContent = new BEROctetString(encryptedContent); - - EncryptedContentInfo eci = CMSUtils.getEncryptedContentInfo( - content.getContentType(), - encAlgId, - encryptedContent); + EncryptedContentInfo encryptedContentInfo = CMSUtils.getEncryptedContentInfo(content, contentEncryptor, + encryptedContent); ASN1Set unprotectedAttrSet = CMSUtils.getAttrBERSet(unprotectedAttributeGenerator); - ContentInfo contentInfo = new ContentInfo( - CMSObjectIdentifiers.encryptedData, - new EncryptedData(eci, unprotectedAttrSet)); + EncryptedData encryptedData = new EncryptedData(encryptedContentInfo, unprotectedAttrSet); + + ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.encryptedData, encryptedData); return new CMSEncryptedData(contentInfo); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java index 24c925a650..2680fd1091 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataGenerator.java @@ -5,7 +5,9 @@ import java.io.OutputStream; import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; import org.bouncycastle.asn1.cms.ContentInfo; @@ -72,15 +74,17 @@ private CMSEnvelopedData doGenerate( throw new CMSException(""); } - byte[] encryptedContent = bOut.toByteArray(); + ASN1OctetString encryptedContent = new BEROctetString(bOut.toByteArray()); - EncryptedContentInfo eci = CMSUtils.getEncryptedContentInfo(content, contentEncryptor, encryptedContent); + EncryptedContentInfo encryptedContentInfo = CMSUtils.getEncryptedContentInfo(content, contentEncryptor, + encryptedContent); ASN1Set unprotectedAttrSet = CMSUtils.getAttrBERSet(unprotectedAttributeGenerator); - ContentInfo contentInfo = new ContentInfo( - CMSObjectIdentifiers.envelopedData, - new EnvelopedData(originatorInfo, new DERSet(recipientInfos), eci, unprotectedAttrSet)); + EnvelopedData envelopedData = new EnvelopedData(originatorInfo, new DERSet(recipientInfos), + encryptedContentInfo, unprotectedAttrSet); + + ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.envelopedData, envelopedData); return new CMSEnvelopedData(contentInfo); } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java index 349f0ea357..fde239f28c 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSEnvelopedDataStreamGenerator.java @@ -71,9 +71,9 @@ private ASN1Integer getVersion(ASN1EncodableVector recipientInfos) if (unprotectedAttributeGenerator != null) { // mark unprotected attributes as non-null. - return new ASN1Integer(EnvelopedData.calculateVersion(originatorInfo, new DLSet(recipientInfos), new DLSet())); + return ASN1Integer.valueOf(EnvelopedData.calculateVersion(originatorInfo, new DLSet(recipientInfos), new DLSet())); } - return new ASN1Integer(EnvelopedData.calculateVersion(originatorInfo, new DLSet(recipientInfos), null)); + return ASN1Integer.valueOf(EnvelopedData.calculateVersion(originatorInfo, new DLSet(recipientInfos), null)); } protected OutputStream open( @@ -83,36 +83,25 @@ protected OutputStream open( OutputEncryptor encryptor) throws IOException { - // // ContentInfo - // BERSequenceGenerator cGen = new BERSequenceGenerator(out); - cGen.addObject(CMSObjectIdentifiers.envelopedData); - // - // Encrypted Data - // + // EnvelopedData BERSequenceGenerator envGen = new BERSequenceGenerator(cGen.getRawOutputStream(), 0, true); - envGen.addObject(getVersion(recipientInfos)); - CMSUtils.addOriginatorInfoToGenerator(envGen, originatorInfo); - CMSUtils.addRecipientInfosToGenerator(recipientInfos, envGen, _berEncodeRecipientSet); - BERSequenceGenerator eiGen = new BERSequenceGenerator(envGen.getRawOutputStream()); - - eiGen.addObject(dataType); - - AlgorithmIdentifier encAlgId = encryptor.getAlgorithmIdentifier(); - - eiGen.getRawOutputStream().write(encAlgId.getEncoded()); + // EncryptedContentInfo + BERSequenceGenerator eciGen = new BERSequenceGenerator(envGen.getRawOutputStream()); + eciGen.addObject(dataType); + eciGen.addObject(encryptor.getAlgorithmIdentifier()); - OutputStream octetStream = CMSUtils.createBEROctetOutputStream( - eiGen.getRawOutputStream(), 0, false, _bufferSize); + // encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL (EncryptedContent ::= OCTET STRING) + OutputStream ecStream = CMSUtils.createBEROctetOutputStream(eciGen.getRawOutputStream(), 0, false, _bufferSize); - return new CmsEnvelopedDataOutputStream(encryptor, octetStream, cGen, envGen, eiGen); + return new CmsEnvelopedDataOutputStream(encryptor, ecStream, cGen, envGen, eciGen); } protected OutputStream open( diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java index 60509c23e7..c6f7c2b116 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataParser.java @@ -447,7 +447,7 @@ public static OutputStream replaceSigners( digestAlgs.add(HELPER.fixDigestAlgID(signer.getDigestAlgorithmID(), dgstAlgFinder)); } AlgorithmIdentifier[] newDigestAlgIds = (AlgorithmIdentifier[])digestAlgs.toArray(new AlgorithmIdentifier[digestAlgs.size()]); - sigGen.getRawOutputStream().write(new DLSet(newDigestAlgIds).getEncoded()); + sigGen.addObject(new DLSet(newDigestAlgIds)); writeEncapContentInfoToGenerator(signedData, sigGen); @@ -463,7 +463,7 @@ public static OutputStream replaceSigners( signerInfos.add(signer.toASN1Structure()); } - sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); + sigGen.addObject(new DERSet(signerInfos)); sigGen.close(); @@ -508,7 +508,7 @@ public static OutputStream replaceCertificatesAndCRLs( sigGen.addObject(signedData.getVersion()); // digests - sigGen.getRawOutputStream().write(signedData.getDigestAlgorithms().toASN1Primitive().getEncoded()); + sigGen.addObject(signedData.getDigestAlgorithms()); writeEncapContentInfoToGenerator(signedData, sigGen); @@ -538,7 +538,7 @@ public static OutputStream replaceCertificatesAndCRLs( if (asn1Certs.size() > 0) { - sigGen.getRawOutputStream().write(new DERTaggedObject(false, 0, asn1Certs).getEncoded()); + sigGen.addObject(new DERTaggedObject(false, 0, asn1Certs)); } } @@ -548,11 +548,11 @@ public static OutputStream replaceCertificatesAndCRLs( if (asn1Crls.size() > 0) { - sigGen.getRawOutputStream().write(new DERTaggedObject(false, 1, asn1Crls).getEncoded()); + sigGen.addObject(new DERTaggedObject(false, 1, asn1Crls)); } } - sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); + sigGen.addObject(signedData.getSignerInfos()); sigGen.close(); @@ -573,11 +573,11 @@ static void writeSetToGeneratorTagged( { if (asn1SetParser instanceof BERSetParser) { - asn1Gen.getRawOutputStream().write(new BERTaggedObject(false, tagNo, asn1Set).getEncoded()); + new BERTaggedObject(false, tagNo, asn1Set).encodeTo(asn1Gen.getRawOutputStream()); } else { - asn1Gen.getRawOutputStream().write(new DERTaggedObject(false, tagNo, asn1Set).getEncoded()); + new DERTaggedObject(false, tagNo, asn1Set).encodeTo(asn1Gen.getRawOutputStream()); } } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamEditor.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamEditor.java index b1a5cfc1a7..395a186841 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamEditor.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamEditor.java @@ -81,13 +81,13 @@ public static OutputStream addDigestAlgorithm(OutputStream out, InputStream orig { throw new CMSException("unable to find digest algorithm"); } - sigGen.getRawOutputStream().write(new DERSet(digestAlgs).getEncoded()); + sigGen.addObject(new DERSet(digestAlgs)); CMSSignedDataParser.writeEncapContentInfoToGenerator(signedData, sigGen); CMSSignedDataParser.writeSetToGeneratorTagged(sigGen, signedData.getCertificates(), 0); CMSSignedDataParser.writeSetToGeneratorTagged(sigGen, signedData.getCrls(), 1); - sigGen.getRawOutputStream().write(signedData.getSignerInfos().toASN1Primitive().getEncoded()); + sigGen.addObject(signedData.getSignerInfos()); sigGen.close(); sGen.close(); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java index 15b6c8a6ab..2b2ae30ea9 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataStreamGenerator.java @@ -186,18 +186,12 @@ public OutputStream open( // // TODO signedAttrs must be present for all signers // } - // // ContentInfo - // BERSequenceGenerator sGen = new BERSequenceGenerator(out); - sGen.addObject(CMSObjectIdentifiers.signedData); - // - // Signed Data - // + // SignedData BERSequenceGenerator sigGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true); - sigGen.addObject(calculateVersion(eContentType)); Set digestAlgs = new HashSet(); @@ -224,23 +218,24 @@ public OutputStream open( } - sigGen.getRawOutputStream().write(CMSUtils.convertToDlSet(digestAlgs).getEncoded()); - - BERSequenceGenerator eiGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); - eiGen.addObject(eContentType); + sigGen.addObject(CMSUtils.convertToDlSet(digestAlgs)); - // If encapsulating, add the data as an octet string in the sequence - OutputStream encapStream = encapsulate - ? CMSUtils.createBEROctetOutputStream(eiGen.getRawOutputStream(), 0, true, _bufferSize) + // EncapsulatedContentInfo + BERSequenceGenerator eciGen = new BERSequenceGenerator(sigGen.getRawOutputStream()); + eciGen.addObject(eContentType); + + // eContent [0] EXPLICIT OCTET STRING OPTIONAL + OutputStream ecStream = encapsulate + ? CMSUtils.createBEROctetOutputStream(eciGen.getRawOutputStream(), 0, true, _bufferSize) : null; // Also send the data to 'dataOutputStream' if necessary - OutputStream contentStream = CMSUtils.getSafeTeeOutputStream(dataOutputStream, encapStream); + OutputStream contentStream = CMSUtils.getSafeTeeOutputStream(dataOutputStream, ecStream); // Let all the signers see the data as it is written OutputStream sigStream = CMSUtils.attachSignersToOutputStream(signerGens, contentStream); - return new CmsSignedDataOutputStream(sigStream, eContentType, sGen, sigGen, eiGen); + return new CmsSignedDataOutputStream(sigStream, eContentType, sGen, sigGen, eciGen); } /** @@ -330,7 +325,7 @@ else if (tagged.getTagNo() == 3) if (otherCert) { - return new ASN1Integer(5); + return ASN1Integer.FIVE; } if (crls != null) // no need to check if otherCert is true @@ -347,30 +342,30 @@ else if (tagged.getTagNo() == 3) if (otherCrl) { - return new ASN1Integer(5); + return ASN1Integer.FIVE; } if (attrCertV2Found) { - return new ASN1Integer(4); + return ASN1Integer.FOUR; } if (attrCertV1Found) { - return new ASN1Integer(3); + return ASN1Integer.THREE; } if (checkForVersion3(_signers, signerGens)) { - return new ASN1Integer(3); + return ASN1Integer.THREE; } if (!CMSObjectIdentifiers.data.equals(contentOid)) { - return new ASN1Integer(3); + return ASN1Integer.THREE; } - return new ASN1Integer(1); + return ASN1Integer.ONE; } private static boolean checkForVersion3(List signerInfos, List signerInfoGens) @@ -456,14 +451,14 @@ public void close() { ASN1Set certSet = CMSUtils.createBerSetFromList(certs); - _sigGen.getRawOutputStream().write(new BERTaggedObject(false, 0, certSet).getEncoded()); + _sigGen.addObject(new BERTaggedObject(false, 0, certSet)); } if (crls.size() != 0) { ASN1Set crlSet = CMSUtils.createBerSetFromList(crls); - _sigGen.getRawOutputStream().write(new BERTaggedObject(false, 1, crlSet).getEncoded()); + _sigGen.addObject(new BERTaggedObject(false, 1, crlSet)); } // @@ -525,8 +520,8 @@ public void close() signerInfos.add(signer.toASN1Structure()); } } - - _sigGen.getRawOutputStream().write(new DERSet(signerInfos).getEncoded()); + + _sigGen.addObject(new DERSet(signerInfos)); _sigGen.close(); _sGen.close(); diff --git a/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java b/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java index 8a011c9afe..539102c901 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java +++ b/pkix/src/main/java/org/bouncycastle/cms/CMSUtils.java @@ -61,18 +61,16 @@ class CMSUtils { - private static final Set des = new HashSet(); + private static final Set desAlgs = new HashSet(); private static final Set mqvAlgs = new HashSet(); private static final Set ecAlgs = new HashSet(); private static final Set gostAlgs = new HashSet(); static { - des.add("DES"); - des.add("DESEDE"); - des.add(OIWObjectIdentifiers.desCBC.getId()); - des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId()); - des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId()); + desAlgs.add(OIWObjectIdentifiers.desCBC); + desAlgs.add(PKCSObjectIdentifiers.des_EDE3_CBC); + desAlgs.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap); mqvAlgs.add(X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme); mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme); @@ -113,14 +111,13 @@ static boolean isGOST(ASN1ObjectIdentifier algorithm) static boolean isRFC2631(ASN1ObjectIdentifier algorithm) { - return algorithm.equals(PKCSObjectIdentifiers.id_alg_ESDH) || algorithm.equals(PKCSObjectIdentifiers.id_alg_SSDH); + return PKCSObjectIdentifiers.id_alg_ESDH.equals(algorithm) + || PKCSObjectIdentifiers.id_alg_SSDH.equals(algorithm); } - static boolean isDES(String algorithmID) + static boolean isDES(ASN1ObjectIdentifier algorithm) { - String name = Strings.toUpperCase(algorithmID); - - return des.contains(name); + return desAlgs.contains(algorithm); } static boolean isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2) @@ -422,24 +419,13 @@ static OutputStream getSafeTeeOutputStream(OutputStream s1, s1, s2); } - static EncryptedContentInfo getEncryptedContentInfo(CMSTypedData content, OutputEncryptor contentEncryptor, byte[] encryptedContent) + static EncryptedContentInfo getEncryptedContentInfo(CMSTypedData content, OutputEncryptor contentEncryptor, + ASN1OctetString encryptedContent) { - return getEncryptedContentInfo( - content.getContentType(), - contentEncryptor.getAlgorithmIdentifier(), + return new EncryptedContentInfo(content.getContentType(), contentEncryptor.getAlgorithmIdentifier(), encryptedContent); } - static EncryptedContentInfo getEncryptedContentInfo(ASN1ObjectIdentifier encryptedContentType, AlgorithmIdentifier encAlgId, byte[] encryptedContent) - { - ASN1OctetString encContent = new BEROctetString(encryptedContent); - - return new EncryptedContentInfo( - encryptedContentType, - encAlgId, - encContent); - } - static ASN1EncodableVector getRecipentInfos(GenericKey encKey, List recipientInfoGenerators) throws CMSException { @@ -460,11 +446,11 @@ static void addRecipientInfosToGenerator(ASN1EncodableVector recipientInfos, BER { if (berEncodeRecipientSet) { - authGen.getRawOutputStream().write(new BERSet(recipientInfos).getEncoded()); + new BERSet(recipientInfos).encodeTo(authGen.getRawOutputStream()); } else { - authGen.getRawOutputStream().write(new DERSet(recipientInfos).getEncoded()); + new DERSet(recipientInfos).encodeTo(authGen.getRawOutputStream()); } } diff --git a/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInfoGenerator.java index 7bc013ac70..34c60351ad 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInfoGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/KEMRecipientInfoGenerator.java @@ -55,7 +55,7 @@ public final RecipientInfo generate(GenericKey contentEncryptionKey) } return new RecipientInfo(new OtherRecipientInfo(CMSObjectIdentifiers.id_ori_kem, - new KEMRecipientInfo(recipId, wrapper.getAlgorithmIdentifier(), new DEROctetString(wrapper.getEncapsulation()), wrapper.getKdfAlgorithmIdentifier(), new ASN1Integer(wrapper.getKekLength()), null, wrapper.getWrapAlgorithmIdentifier(), + new KEMRecipientInfo(recipId, wrapper.getAlgorithmIdentifier(), new DEROctetString(wrapper.getEncapsulation()), wrapper.getKdfAlgorithmIdentifier(), ASN1Integer.valueOf(wrapper.getKekLength()), null, wrapper.getWrapAlgorithmIdentifier(), new DEROctetString(encryptedKeyBytes)))); } } \ No newline at end of file diff --git a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java index a7bf36e5d0..009d9d9023 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/KeyAgreeRecipientInfoGenerator.java @@ -1,6 +1,8 @@ package org.bouncycastle.cms; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; @@ -18,64 +20,50 @@ public abstract class KeyAgreeRecipientInfoGenerator implements RecipientInfoGenerator { - private ASN1ObjectIdentifier keyAgreementOID; - private ASN1ObjectIdentifier keyEncryptionOID; - private SubjectPublicKeyInfo originatorKeyInfo; + private final ASN1ObjectIdentifier keyAgreementOID; + private final ASN1ObjectIdentifier keyEncryptionOID; + private final SubjectPublicKeyInfo originatorKeyInfo; - protected KeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID, SubjectPublicKeyInfo originatorKeyInfo, ASN1ObjectIdentifier keyEncryptionOID) + protected KeyAgreeRecipientInfoGenerator(ASN1ObjectIdentifier keyAgreementOID, + SubjectPublicKeyInfo originatorKeyInfo, ASN1ObjectIdentifier keyEncryptionOID) { this.originatorKeyInfo = originatorKeyInfo; this.keyAgreementOID = keyAgreementOID; this.keyEncryptionOID = keyEncryptionOID; } - public RecipientInfo generate(GenericKey contentEncryptionKey) - throws CMSException + public RecipientInfo generate(GenericKey contentEncryptionKey) throws CMSException { - OriginatorIdentifierOrKey originator = new OriginatorIdentifierOrKey( - createOriginatorPublicKey(originatorKeyInfo)); + OriginatorPublicKey originatorPublicKey = createOriginatorPublicKey(originatorKeyInfo); + OriginatorIdentifierOrKey originator = new OriginatorIdentifierOrKey(originatorPublicKey); - AlgorithmIdentifier keyEncAlg; - if (CMSUtils.isDES(keyEncryptionOID.getId()) || keyEncryptionOID.equals(PKCSObjectIdentifiers.id_alg_CMSRC2wrap)) + ASN1Encodable keyEncAlgParams = null; + if (CMSUtils.isDES(keyEncryptionOID) || PKCSObjectIdentifiers.id_alg_CMSRC2wrap.equals(keyEncryptionOID)) { - keyEncAlg = new AlgorithmIdentifier(keyEncryptionOID, DERNull.INSTANCE); + keyEncAlgParams = DERNull.INSTANCE; } else if (CMSUtils.isGOST(keyAgreementOID)) { - keyEncAlg = new AlgorithmIdentifier(keyEncryptionOID, new Gost2814789KeyWrapParameters(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet)); - } - else - { - keyEncAlg = new AlgorithmIdentifier(keyEncryptionOID); + keyEncAlgParams = new Gost2814789KeyWrapParameters(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet); } - AlgorithmIdentifier keyAgreeAlg = new AlgorithmIdentifier(keyAgreementOID, keyEncAlg); + AlgorithmIdentifier keyEncAlgorithm = new AlgorithmIdentifier(keyEncryptionOID, keyEncAlgParams); + AlgorithmIdentifier keyAgreeAlgorithm = new AlgorithmIdentifier(keyAgreementOID, keyEncAlgorithm); - ASN1Sequence recipients = generateRecipientEncryptedKeys(keyAgreeAlg, keyEncAlg, contentEncryptionKey); - byte[] userKeyingMaterial = getUserKeyingMaterial(keyAgreeAlg); + ASN1Sequence recipients = generateRecipientEncryptedKeys(keyAgreeAlgorithm, keyEncAlgorithm, contentEncryptionKey); - if (userKeyingMaterial != null) - { - return new RecipientInfo(new KeyAgreeRecipientInfo(originator, new DEROctetString(userKeyingMaterial), - keyAgreeAlg, recipients)); - } - else - { - return new RecipientInfo(new KeyAgreeRecipientInfo(originator, null, keyAgreeAlg, recipients)); - } + ASN1OctetString ukm = DEROctetString.fromContentsOptional(getUserKeyingMaterial(keyAgreeAlgorithm)); + + return new RecipientInfo(new KeyAgreeRecipientInfo(originator, ukm, keyAgreeAlgorithm, recipients)); } protected OriginatorPublicKey createOriginatorPublicKey(SubjectPublicKeyInfo originatorKeyInfo) { - return new OriginatorPublicKey( - originatorKeyInfo.getAlgorithm(), - originatorKeyInfo.getPublicKeyData().getBytes()); + return new OriginatorPublicKey(originatorKeyInfo.getAlgorithm(), originatorKeyInfo.getPublicKeyData()); } - protected abstract ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncAlgorithm, GenericKey contentEncryptionKey) - throws CMSException; - - protected abstract byte[] getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlgorithm) - throws CMSException; + protected abstract ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, + AlgorithmIdentifier keyEncAlgorithm, GenericKey contentEncryptionKey) throws CMSException; -} \ No newline at end of file + protected abstract byte[] getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlgorithm) throws CMSException; +} diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java index 5c499edeab..c21ec9a0fa 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipient.java @@ -253,8 +253,8 @@ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, Algor { try { - AlgorithmIdentifier wrapAlg = - AlgorithmIdentifier.getInstance(keyEncryptionAlgorithm.getParameters()); + AlgorithmIdentifier wrapAlgID = AlgorithmIdentifier.getInstance(keyEncryptionAlgorithm.getParameters()); + ASN1ObjectIdentifier wrapAlgOID = wrapAlgID.getAlgorithm(); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(senderKey.getEncoded()); KeyFactory fact = helper.createKeyFactory(senderKey.getAlgorithm().getAlgorithm()); @@ -262,43 +262,50 @@ protected Key extractSecretKey(AlgorithmIdentifier keyEncryptionAlgorithm, Algor try { - SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlg, - senderPublicKey, userKeyingMaterial, recipientKey, ecc_cms_Generator); + SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlgID, senderPublicKey, + userKeyingMaterial, recipientKey, ecc_cms_Generator); - if (wrapAlg.getAlgorithm().equals(CryptoProObjectIdentifiers.id_Gost28147_89_None_KeyWrap) - || wrapAlg.getAlgorithm().equals(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_KeyWrap)) + if (CryptoProObjectIdentifiers.id_Gost28147_89_None_KeyWrap.equals(wrapAlgOID) || + CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_KeyWrap.equals(wrapAlgOID)) { Gost2814789EncryptedKey encKey = Gost2814789EncryptedKey.getInstance(encryptedContentEncryptionKey); - Gost2814789KeyWrapParameters wrapParams = Gost2814789KeyWrapParameters.getInstance(wrapAlg.getParameters()); + Gost2814789KeyWrapParameters wrapParams = Gost2814789KeyWrapParameters.getInstance( + wrapAlgID.getParameters()); - Cipher keyCipher = helper.createCipher(wrapAlg.getAlgorithm()); + Cipher keyCipher = helper.createCipher(wrapAlgOID); - keyCipher.init(Cipher.UNWRAP_MODE, agreedWrapKey, new GOST28147WrapParameterSpec(wrapParams.getEncryptionParamSet(), userKeyingMaterial.getOctets())); + keyCipher.init(Cipher.UNWRAP_MODE, agreedWrapKey, + new GOST28147WrapParameterSpec(wrapParams.getEncryptionParamSet(), userKeyingMaterial.getOctets())); - return keyCipher.unwrap(Arrays.concatenate(encKey.getEncryptedKey(), encKey.getMacKey()), helper.getBaseCipherName(contentEncryptionAlgorithm.getAlgorithm()), Cipher.SECRET_KEY); + byte[] wrappedKey = Arrays.concatenate(encKey.getEncryptedKey(), encKey.getMacKey()); + return keyCipher.unwrap(wrappedKey, helper.getBaseCipherName(contentEncryptionAlgorithm.getAlgorithm()), + Cipher.SECRET_KEY); } - return unwrapSessionKey(wrapAlg.getAlgorithm(), agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), encryptedContentEncryptionKey); + return unwrapSessionKey(wrapAlgOID, agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), + encryptedContentEncryptionKey); } catch (InvalidKeyException e) { // might be a pre-RFC 5753 message if (possibleOldMessages.contains(keyEncryptionAlgorithm.getAlgorithm())) { - SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlg, + SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlgID, senderPublicKey, userKeyingMaterial, recipientKey, old_ecc_cms_Generator); - return unwrapSessionKey(wrapAlg.getAlgorithm(), agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), encryptedContentEncryptionKey); + return unwrapSessionKey(wrapAlgOID, agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), + encryptedContentEncryptionKey); } // one last try - people do actually do this it turns out if (userKeyingMaterial != null) { try { - SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlg, + SecretKey agreedWrapKey = calculateAgreedWrapKey(keyEncryptionAlgorithm, wrapAlgID, senderPublicKey, userKeyingMaterial, recipientKey, simple_ecc_cmsGenerator); - return unwrapSessionKey(wrapAlg.getAlgorithm(), agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), encryptedContentEncryptionKey); + return unwrapSessionKey(wrapAlgOID, agreedWrapKey, contentEncryptionAlgorithm.getAlgorithm(), + encryptedContentEncryptionKey); } catch (InvalidKeyException ex) { diff --git a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java index d2dc76a569..c35c6578ec 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java @@ -146,19 +146,19 @@ public JceKeyAgreeRecipientInfoGenerator addRecipient(byte[] subjectKeyID, Publi return this; } - public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, GenericKey contentEncryptionKey) - throws CMSException + public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeAlgorithm, + AlgorithmIdentifier keyEncryptionAlgorithm, GenericKey contentEncryptionKey) throws CMSException { if (recipientIDs.isEmpty()) { throw new CMSException("No recipients associated with generator - use addRecipient()"); } - init(keyAgreeAlgorithm.getAlgorithm()); + ASN1ObjectIdentifier keyAgreementOID = keyAgreeAlgorithm.getAlgorithm(); - PrivateKey senderPrivateKey = this.senderPrivateKey; + init(keyAgreementOID); - ASN1ObjectIdentifier keyAgreementOID = keyAgreeAlgorithm.getAlgorithm(); + PrivateKey senderPrivateKey = this.senderPrivateKey; ASN1EncodableVector recipientEncryptedKeys = new ASN1EncodableVector(); for (int i = 0; i != recipientIDs.size(); i++) @@ -169,7 +169,7 @@ public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeA try { AlgorithmParameterSpec agreementParamSpec; - ASN1ObjectIdentifier keyEncAlg = keyEncryptionAlgorithm.getAlgorithm(); + ASN1ObjectIdentifier keyEncryptionOID = keyEncryptionAlgorithm.getAlgorithm(); if (CMSUtils.isMQV(keyAgreementOID)) { @@ -177,7 +177,8 @@ public ASN1Sequence generateRecipientEncryptedKeys(AlgorithmIdentifier keyAgreeA } else if (CMSUtils.isEC(keyAgreementOID)) { - byte[] ukmKeyingMaterial = ecc_cms_Generator.generateKDFMaterial(keyEncryptionAlgorithm, keySizeProvider.getKeySize(keyEncAlg), userKeyingMaterial); + byte[] ukmKeyingMaterial = ecc_cms_Generator.generateKDFMaterial(keyEncryptionAlgorithm, + keySizeProvider.getKeySize(keyEncryptionOID), userKeyingMaterial); agreementParamSpec = new UserKeyingMaterialSpec(ukmKeyingMaterial); } @@ -217,18 +218,19 @@ else if (CMSUtils.isGOST(keyAgreementOID)) keyAgreement.init(senderPrivateKey, agreementParamSpec, random); keyAgreement.doPhase(recipientPublicKey, true); - SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncAlg.getId()); + SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncryptionOID.getId()); EnvelopedDataHelper keyWrapHelper = (wrappingHelper != null) ? wrappingHelper : helper; // Wrap the content encryption key with the agreement key - Cipher keyEncryptionCipher = keyWrapHelper.createCipher(keyEncAlg); - ASN1OctetString encryptedKey; + Cipher keyEncryptionCipher = keyWrapHelper.createCipher(keyEncryptionOID); - if (keyEncAlg.equals(CryptoProObjectIdentifiers.id_Gost28147_89_None_KeyWrap) - || keyEncAlg.equals(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_KeyWrap)) + byte[] encryptedKeyOctets; + if (CryptoProObjectIdentifiers.id_Gost28147_89_None_KeyWrap.equals(keyEncryptionOID) || + CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_KeyWrap.equals(keyEncryptionOID)) { - keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, new GOST28147WrapParameterSpec(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet, userKeyingMaterial)); + keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, + new GOST28147WrapParameterSpec(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet, userKeyingMaterial)); byte[] encKeyBytes = keyEncryptionCipher.wrap(keyWrapHelper.getJceKey(contentEncryptionKey)); @@ -236,18 +238,16 @@ else if (CMSUtils.isGOST(keyAgreementOID)) Arrays.copyOfRange(encKeyBytes, 0, encKeyBytes.length - 4), Arrays.copyOfRange(encKeyBytes, encKeyBytes.length - 4, encKeyBytes.length)); - encryptedKey = new DEROctetString(encKey.getEncoded(ASN1Encoding.DER)); + encryptedKeyOctets = encKey.getEncoded(ASN1Encoding.DER); } else { keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, random); - byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(keyWrapHelper.getJceKey(contentEncryptionKey)); - - encryptedKey = new DEROctetString(encryptedKeyBytes); + encryptedKeyOctets = keyEncryptionCipher.wrap(keyWrapHelper.getJceKey(contentEncryptionKey)); } - recipientEncryptedKeys.add(new RecipientEncryptedKey(karId, encryptedKey)); + recipientEncryptedKeys.add(new RecipientEncryptedKey(karId, new DEROctetString(encryptedKeyOctets))); } catch (GeneralSecurityException e) { @@ -269,18 +269,14 @@ protected byte[] getUserKeyingMaterial(AlgorithmIdentifier keyAgreeAlg) if (ephemeralKP != null) { - OriginatorPublicKey originatorPublicKey = createOriginatorPublicKey(SubjectPublicKeyInfo.getInstance(ephemeralKP.getPublic().getEncoded())); + OriginatorPublicKey originatorPublicKey = createOriginatorPublicKey( + SubjectPublicKeyInfo.getInstance(ephemeralKP.getPublic().getEncoded())); try { - if (userKeyingMaterial != null) - { - return new MQVuserKeyingMaterial(originatorPublicKey, new DEROctetString(userKeyingMaterial)).getEncoded(); - } - else - { - return new MQVuserKeyingMaterial(originatorPublicKey, null).getEncoded(); - } + ASN1OctetString addedukm = DEROctetString.fromContentsOptional(userKeyingMaterial); + + return new MQVuserKeyingMaterial(originatorPublicKey, addedukm).getEncoded(); } catch (IOException e) { diff --git a/pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java b/pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java index f6deeab2ca..bcc1e5302b 100644 --- a/pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/openssl/MiscPEMGenerator.java @@ -108,9 +108,9 @@ else if (algOID.equals(dsaOids[0]) || algOID.equals(dsaOids[1])) type = "DSA PRIVATE KEY"; DSAParameter p = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); - ASN1EncodableVector v = new ASN1EncodableVector(); + ASN1EncodableVector v = new ASN1EncodableVector(6); - v.add(new ASN1Integer(0)); + v.add(ASN1Integer.ZERO); v.add(new ASN1Integer(p.getP())); v.add(new ASN1Integer(p.getQ())); v.add(new ASN1Integer(p.getG())); diff --git a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java index d5288df787..0c298faacc 100644 --- a/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/openssl/jcajce/JceOpenSSLPKCS8EncryptorBuilder.java @@ -208,7 +208,7 @@ else if (PEMUtilities.isPKCS12(algOID)) random.nextBytes(salt); v.add(new DEROctetString(salt)); - v.add(new ASN1Integer(iterationCount)); + v.add(ASN1Integer.valueOf(iterationCount)); algID = new AlgorithmIdentifier(algOID, PKCS12PBEParams.getInstance(new DERSequence(v))); diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java index 9e641e32bd..e48dbeae88 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java @@ -331,7 +331,7 @@ public AlgorithmIdentifier find(AlgorithmIdentifier sigAlgId) return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256); } - return new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, new ASN1Integer(512)); + return new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, ASN1Integer.valueOf(512)); } ASN1ObjectIdentifier digAlgOid; diff --git a/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java index 19aa1a5ed3..9ddc41414f 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java @@ -77,7 +77,7 @@ private static RSASSAPSSparams createPSSParams(AlgorithmIdentifier hashAlgId, in return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), - new ASN1Integer(saltSize), + ASN1Integer.valueOf(saltSize), RSASSAPSSparams.DEFAULT_TRAILER_FIELD); } diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java index ccd54f5c90..a7c27b642e 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java @@ -400,8 +400,8 @@ private static RSASSAPSSparams createPSSParams(PSSParameterSpec pssSpec) return new RSASSAPSSparams( digId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, mgfDig), - new ASN1Integer(pssSpec.getSaltLength()), - new ASN1Integer(pssSpec.getTrailerField())); + ASN1Integer.valueOf(pssSpec.getSaltLength()), + ASN1Integer.valueOf(pssSpec.getTrailerField())); } private static ASN1Sequence createCompParams(CompositeAlgorithmSpec compSpec) diff --git a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java index 5e9bbee3b6..8fbba69852 100644 --- a/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java +++ b/pkix/src/main/java/org/bouncycastle/operator/jcajce/JceSymmetricKeyWrapper.java @@ -90,8 +90,7 @@ static AlgorithmIdentifier determineKeyEncAlg(String algorithm, int keySizeInBit } else if (algorithm.startsWith("RC2")) { - return new AlgorithmIdentifier(new ASN1ObjectIdentifier( - "1.2.840.113549.1.9.16.3.7"), new ASN1Integer(58)); + return new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7"), ASN1Integer.valueOf(58)); } else if (algorithm.startsWith("AES") || algorithm.startsWith(NISTObjectIdentifiers.aes.getId())) { diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java index 05a2e4e261..9c1528936c 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampResponseGenerator.java @@ -122,7 +122,7 @@ private PKIStatusInfo getPKIStatusInfo() { ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new ASN1Integer(status)); + v.add(ASN1Integer.valueOf(status)); if (statusStrings.size() > 0) { diff --git a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java index 7f352f7d52..8ea96190e7 100644 --- a/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/tsp/TimeStampTokenGenerator.java @@ -383,19 +383,19 @@ public TimeStampToken generate( ASN1Integer seconds = null; if (accuracySeconds > 0) { - seconds = new ASN1Integer(accuracySeconds); + seconds = ASN1Integer.valueOf(accuracySeconds); } ASN1Integer millis = null; if (accuracyMillis > 0) { - millis = new ASN1Integer(accuracyMillis); + millis = ASN1Integer.valueOf(accuracyMillis); } ASN1Integer micros = null; if (accuracyMicros > 0) { - micros = new ASN1Integer(accuracyMicros); + micros = ASN1Integer.valueOf(accuracyMicros); } accuracy = new Accuracy(seconds, millis, micros); diff --git a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java index 038320aac4..c7dff3d38e 100644 --- a/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java +++ b/pkix/src/test/java/org/bouncycastle/cert/cmp/test/AllTests.java @@ -295,7 +295,7 @@ public void testServerSideKey() CertRepMessage msg = new CertRepMessage(null, new CertResponse[] { new CertResponse( - new ASN1Integer(2), + ASN1Integer.TWO, new PKIStatusInfo(PKIStatus.granted), new CertifiedKeyPair( new CertOrEncCert(CMPCertificate.getInstance(cert.getEncoded())), diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java index b2aeea711c..699d510273 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/BcSignedDataTest.java @@ -1001,7 +1001,7 @@ public void testSHA1WithRSAEncapsulated() public void testEd448() throws Exception { - encapsulatedTest(_signEd448KP, _signEd448Cert, "ED448", new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, new ASN1Integer(512))); + encapsulatedTest(_signEd448KP, _signEd448Cert, "ED448", new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, ASN1Integer.valueOf(512))); } public void testSHA1WithRSAEncapsulatedSubjectKeyID() diff --git a/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java b/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java index 5e41a1c9a0..1b0a8133a9 100644 --- a/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java +++ b/pkix/src/test/java/org/bouncycastle/cms/test/NewSignedDataTest.java @@ -1932,7 +1932,7 @@ public void testEd448() * We confirm here that our implementation defaults to id-shake256-len/512 for the digest algorithm. */ AlgorithmIdentifier expectedDigAlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256_len, - new ASN1Integer(512)); + ASN1Integer.valueOf(512)); detachedTest(_signEd448KP, _signEd448Cert, "Ed448", EdECObjectIdentifiers.id_Ed448, expectedDigAlgId); diff --git a/pkix/src/test/java/org/bouncycastle/dvcs/test/DVCSParseTest.java b/pkix/src/test/java/org/bouncycastle/dvcs/test/DVCSParseTest.java index 1680039c57..72024067ef 100644 --- a/pkix/src/test/java/org/bouncycastle/dvcs/test/DVCSParseTest.java +++ b/pkix/src/test/java/org/bouncycastle/dvcs/test/DVCSParseTest.java @@ -90,7 +90,7 @@ public class DVCSParseTest REQ_CCPD_TOMSK = new DVCSRequest(INFO_CCPD_TOMSK.build(), new Data(DIGEST_CCPD_TOMSK), ID_CCPD_TOMSK); - DVCSCertInfoBuilder certInfoBldr = new DVCSCertInfoBuilder(INFO_CCPD_TOMSK.build(), DIGEST_CCPD_TOMSK, new ASN1Integer(6256), new DVCSTime(new ASN1GeneralizedTime("20121204040643Z"))); + DVCSCertInfoBuilder certInfoBldr = new DVCSCertInfoBuilder(INFO_CCPD_TOMSK.build(), DIGEST_CCPD_TOMSK, ASN1Integer.valueOf(6256), new DVCSTime(new ASN1GeneralizedTime("20121204040643Z"))); certInfoBldr.setDvStatus(new PKIStatusInfo(PKIStatus.granted)); RES_CCPD_TOMSK = new DVCSResponse(certInfoBldr.build()); @@ -107,7 +107,7 @@ public class DVCSParseTest REQ_CPD_TOMSK = new DVCSRequest(INFO_CPD_TOMSK.build(), new Data(Hex.decode(CPD_DATA_TOMSK)), ID_CPD_TOMSK); - certInfoBldr = new DVCSCertInfoBuilder(INFO_CPD_TOMSK2.build(), DIGEST_CPD_TOMSK, new ASN1Integer(6329), new DVCSTime(new ASN1GeneralizedTime("20121205065720Z"))); + certInfoBldr = new DVCSCertInfoBuilder(INFO_CPD_TOMSK2.build(), DIGEST_CPD_TOMSK, ASN1Integer.valueOf(6329), new DVCSTime(new ASN1GeneralizedTime("20121205065720Z"))); certInfoBldr.setDvStatus(new PKIStatusInfo(PKIStatus.granted)); RES_CPD_TOMSK = new DVCSResponse(certInfoBldr.build()); @@ -126,7 +126,7 @@ public class DVCSParseTest REQ_VPKC_TOMSK = new DVCSRequest(INFO_VPKC_TOMSK.build(), new Data(REQ_CERTS), ID_VPKC_TOMSK); - certInfoBldr = new DVCSCertInfoBuilder(INFO_VPKC_TOMSK.build(), DIGEST_VPKC_TOMSK, new ASN1Integer(6257), new DVCSTime(new ASN1GeneralizedTime("20121204040753Z"))); + certInfoBldr = new DVCSCertInfoBuilder(INFO_VPKC_TOMSK.build(), DIGEST_VPKC_TOMSK, ASN1Integer.valueOf(6257), new DVCSTime(new ASN1GeneralizedTime("20121204040753Z"))); certInfoBldr.setDvStatus(new PKIStatusInfo(PKIStatus.granted)); certInfoBldr.setCerts(RES_CERTS); diff --git a/pkix/src/test/java/org/bouncycastle/tsp/test/GenTimeAccuracyUnitTest.java b/pkix/src/test/java/org/bouncycastle/tsp/test/GenTimeAccuracyUnitTest.java index 40ff9400db..a3f07d3bf5 100644 --- a/pkix/src/test/java/org/bouncycastle/tsp/test/GenTimeAccuracyUnitTest.java +++ b/pkix/src/test/java/org/bouncycastle/tsp/test/GenTimeAccuracyUnitTest.java @@ -8,34 +8,29 @@ public class GenTimeAccuracyUnitTest extends TestCase { - private static final ASN1Integer ZERO_VALUE = new ASN1Integer(0); - private static final ASN1Integer ONE_VALUE = new ASN1Integer(1); - private static final ASN1Integer TWO_VALUE = new ASN1Integer(2); - private static final ASN1Integer THREE_VALUE = new ASN1Integer(3); - public void testOneTwoThree() { - GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ONE_VALUE, TWO_VALUE, THREE_VALUE)); + GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ASN1Integer.ONE, ASN1Integer.TWO, ASN1Integer.THREE)); - checkValues(accuracy, ONE_VALUE, TWO_VALUE, THREE_VALUE); + checkValues(accuracy, ASN1Integer.ONE, ASN1Integer.TWO, ASN1Integer.THREE); checkToString(accuracy, "1.002003"); } public void testThreeTwoOne() { - GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(THREE_VALUE, TWO_VALUE, ONE_VALUE)); + GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ASN1Integer.THREE, ASN1Integer.TWO, ASN1Integer.ONE)); - checkValues(accuracy, THREE_VALUE, TWO_VALUE, ONE_VALUE); + checkValues(accuracy, ASN1Integer.THREE, ASN1Integer.TWO, ASN1Integer.ONE); checkToString(accuracy, "3.002001"); } public void testTwoThreeTwo() { - GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(TWO_VALUE, THREE_VALUE, TWO_VALUE)); + GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ASN1Integer.TWO, ASN1Integer.THREE, ASN1Integer.TWO)); - checkValues(accuracy, TWO_VALUE, THREE_VALUE, TWO_VALUE); + checkValues(accuracy, ASN1Integer.TWO, ASN1Integer.THREE, ASN1Integer.TWO); checkToString(accuracy, "2.003002"); } @@ -43,36 +38,36 @@ public void testTwoThreeTwo() public void testZeroTwoThree() { - GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ZERO_VALUE, TWO_VALUE, THREE_VALUE)); + GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ASN1Integer.ZERO, ASN1Integer.TWO, ASN1Integer.THREE)); - checkValues(accuracy, ZERO_VALUE, TWO_VALUE, THREE_VALUE); + checkValues(accuracy, ASN1Integer.ZERO, ASN1Integer.TWO, ASN1Integer.THREE); checkToString(accuracy, "0.002003"); } public void testThreeTwoNull() { - GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(THREE_VALUE, TWO_VALUE, null)); + GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ASN1Integer.THREE, ASN1Integer.TWO, null)); - checkValues(accuracy, THREE_VALUE, TWO_VALUE, ZERO_VALUE); + checkValues(accuracy, ASN1Integer.THREE, ASN1Integer.TWO, ASN1Integer.ZERO); checkToString(accuracy, "3.002000"); } public void testOneNullOne() { - GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ONE_VALUE, null, ONE_VALUE)); + GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ASN1Integer.ONE, null, ASN1Integer.ONE)); - checkValues(accuracy, ONE_VALUE, ZERO_VALUE, ONE_VALUE); + checkValues(accuracy, ASN1Integer.ONE, ASN1Integer.ZERO, ASN1Integer.ONE); checkToString(accuracy, "1.000001"); } public void testZeroNullNull() { - GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ZERO_VALUE, null, null)); + GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ASN1Integer.ZERO, null, null)); - checkValues(accuracy, ZERO_VALUE, ZERO_VALUE, ZERO_VALUE); + checkValues(accuracy, ASN1Integer.ZERO, ASN1Integer.ZERO, ASN1Integer.ZERO); checkToString(accuracy, "0.000000"); } @@ -81,7 +76,7 @@ public void testNullNullNull() { GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(null, null, null)); - checkValues(accuracy, ZERO_VALUE, ZERO_VALUE, ZERO_VALUE); + checkValues(accuracy, ASN1Integer.ZERO, ASN1Integer.ZERO, ASN1Integer.ZERO); checkToString(accuracy, "0.000000"); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java index 4194712703..da219bb1e3 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/CompositePrivateKey.java @@ -8,6 +8,7 @@ import java.util.Collections; import java.util.List; +import org.bouncycastle.asn1.ASN1BitString; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; @@ -16,9 +17,6 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; -import org.bouncycastle.asn1.x9.ECNamedCurveTable; -import org.bouncycastle.crypto.util.PrivateKeyFactory; -import org.bouncycastle.crypto.util.PrivateKeyInfoFactory; import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.interfaces.MLDSAPrivateKey; @@ -269,39 +267,67 @@ public String getFormat() */ public byte[] getEncoded() { - if (this.algorithmIdentifier.getAlgorithm().on(IANAObjectIdentifiers.id_alg)) + ASN1ObjectIdentifier algOid = algorithmIdentifier.getAlgorithm(); + + if (algOid.on(IANAObjectIdentifiers.id_alg)) { try { - byte[] mldsaKey = ((MLDSAPrivateKey)keys.get(0)).getSeed(); - PrivateKeyInfo pki = PrivateKeyInfoFactory.createPrivateKeyInfo(PrivateKeyFactory.createKey(keys.get(1).getEncoded())); - byte[] tradKey = pki.getPrivateKey().getOctets(); - if (keys.get(1).getAlgorithm().contains("Ed")) + PrivateKey key0 = keys.get(0); + PrivateKey key1 = keys.get(1); + + byte[] mldsaSeed = ((MLDSAPrivateKey)key0).getSeed(); + + PrivateKeyInfo pki = PrivateKeyInfo.getInstance(key1.getEncoded()); + + byte[] tradSK; + String key1Algorithm = key1.getAlgorithm(); + if (key1Algorithm.contains("Ed")) { - tradKey = ASN1OctetString.getInstance(tradKey).getOctets(); + tradSK = ASN1OctetString.getInstance(pki.parsePrivateKey()).getOctets(); } - else if (keys.get(1).getAlgorithm().contains("EC")) + else if (key1Algorithm.contains("EC")) { - ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(tradKey); - - tradKey = new ECPrivateKey(ECNamedCurveTable.getByOID( - ASN1ObjectIdentifier.getInstance(ecPrivateKey.getParametersObject())).getCurve().getFieldSize(), ecPrivateKey.getKey(), ecPrivateKey.getParametersObject()).getEncoded(); + ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(pki.parsePrivateKey()); + + /* + * TODO + * - Confirm pki.privateKeyAlgorithm is id_ecPublicKey with X9.62 Parameters namedCurve OID. + * - If ecPrivateKey.parameters are present, must match pki.privateKeyAlgorithm + * The private key MUST be encoded as ECPrivateKey specified in [RFC5915] with the 'NamedCurve' + * parameter set to the OID of the curve, but without the 'publicKey' field. + */ + // TODO Also need to ensure that ECPrivateKey.parameters are present + ASN1BitString publicKey = ecPrivateKey.getPublicKey(); + if (publicKey != null) + { + ecPrivateKey = new ECPrivateKey(ecPrivateKey.getPrivateKey(), ecPrivateKey.getParametersObject(), null); + } + + tradSK = ecPrivateKey.getEncoded(ASN1Encoding.DER); } - return new PrivateKeyInfo(algorithmIdentifier, Arrays.concatenate(mldsaKey, tradKey)).getEncoded(); + else + { + tradSK = pki.getPrivateKey().getOctets(); + } + + return new PrivateKeyInfo(algorithmIdentifier, Arrays.concatenate(mldsaSeed, tradSK)).getEncoded(); } catch (IOException e) { throw new IllegalStateException("unable to encode composite public key: " + e.getMessage()); } } + ASN1EncodableVector v = new ASN1EncodableVector(); - if (algorithmIdentifier.getAlgorithm().equals(MiscObjectIdentifiers.id_composite_key)) + if (MiscObjectIdentifiers.id_composite_key.equals(algOid)) { for (int i = 0; i < keys.size(); i++) { - PrivateKeyInfo info = PrivateKeyInfo.getInstance(keys.get(i).getEncoded()); - v.add(info); + PrivateKeyInfo pki = PrivateKeyInfo.getInstance(keys.get(i).getEncoded()); + + v.add(pki); } try @@ -318,8 +344,9 @@ else if (keys.get(1).getAlgorithm().contains("EC")) byte[] keyEncoding = null; for (int i = 0; i < keys.size(); i++) { - PrivateKeyInfo info = PrivateKeyInfo.getInstance(keys.get(i).getEncoded()); - keyEncoding = Arrays.concatenate(keyEncoding, info.getPrivateKey().getOctets()); + PrivateKeyInfo pki = PrivateKeyInfo.getInstance(keys.get(i).getEncoded()); + + keyEncoding = Arrays.concatenate(keyEncoding, pki.getPrivateKey().getOctets()); } try diff --git a/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java index 576b5f7d4f..15175454f0 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/CompositePublicKey.java @@ -14,8 +14,6 @@ import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.crypto.util.PublicKeyFactory; -import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers; import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.CompositeIndex; @@ -248,13 +246,15 @@ public String getFormat() @Override public byte[] getEncoded() { - if (this.algorithmIdentifier.getAlgorithm().on(IANAObjectIdentifiers.id_alg)) + ASN1ObjectIdentifier algOid = algorithmIdentifier.getAlgorithm(); + + if (algOid.on(IANAObjectIdentifiers.id_alg)) { try { - byte[] mldsaKey = org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(org.bouncycastle.pqc.crypto.util.PublicKeyFactory.createKey(keys.get(0).getEncoded())).getPublicKeyData().getBytes(); - byte[] tradKey = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(PublicKeyFactory.createKey(keys.get(1).getEncoded())).getPublicKeyData().getBytes(); - return new SubjectPublicKeyInfo(getAlgorithmIdentifier(), Arrays.concatenate(mldsaKey, tradKey)).getEncoded(); + byte[] mldsaPK = SubjectPublicKeyInfo.getInstance(keys.get(0).getEncoded()).getPublicKeyData().getOctets(); + byte[] tradPK = SubjectPublicKeyInfo.getInstance(keys.get(1).getEncoded()).getPublicKeyData().getOctets(); + return new SubjectPublicKeyInfo(algorithmIdentifier, Arrays.concatenate(mldsaPK, tradPK)).getEncoded(ASN1Encoding.DER); } catch (IOException e) { @@ -266,18 +266,20 @@ public byte[] getEncoded() for (int i = 0; i < keys.size(); i++) { - if (this.algorithmIdentifier.getAlgorithm().equals(MiscObjectIdentifiers.id_composite_key)) + SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded()); + + if (MiscObjectIdentifiers.id_composite_key.equals(algOid)) { //Legacy, component is the whole SubjectPublicKeyInfo - v.add(SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded())); + v.add(spki); } else { //component is the value of subjectPublicKey from SubjectPublicKeyInfo - SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(keys.get(i).getEncoded()); - v.add(keyInfo.getPublicKeyData()); + v.add(spki.getPublicKeyData()); } } + try { return new SubjectPublicKeyInfo(this.algorithmIdentifier, new DERSequence(v)).getEncoded(ASN1Encoding.DER); @@ -288,31 +290,26 @@ public byte[] getEncoded() } } - public int hashCode() { - return keys.hashCode(); + return algorithmIdentifier.hashCode() ^ keys.hashCode(); } - public boolean equals(Object o) + public boolean equals(Object obj) { - if (o == this) + if (obj == this) { return true; } - if (o instanceof CompositePublicKey) + if (!(obj instanceof CompositePublicKey)) { - boolean isEqual = true; - CompositePublicKey comparedKey = (CompositePublicKey)o; - if (!comparedKey.getAlgorithmIdentifier().equals(this.algorithmIdentifier) || !this.keys.equals(comparedKey.keys)) - { - isEqual = false; - } - - return isEqual; + return false; } - return false; + CompositePublicKey that = (CompositePublicKey)obj; + + return this.algorithmIdentifier.equals(that.algorithmIdentifier) + && this.keys.equals(that.keys); } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/CompositeUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/CompositeUtil.java index d60d6f66ec..a5df9e781b 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/CompositeUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/CompositeUtil.java @@ -15,7 +15,7 @@ class CompositeUtil { algorithmOids.put("MLDSA44-RSA2048-PSS-SHA256", IANAObjectIdentifiers.id_MLDSA44_RSA2048_PSS_SHA256); algorithmOids.put("MLDSA44-RSA2048-PKCS15-SHA256", IANAObjectIdentifiers.id_MLDSA44_RSA2048_PKCS15_SHA256); - algorithmOids.put("MLDSA44-Ed25519-SHA512", IANAObjectIdentifiers.id_MLDSA44_Ed25519_SHA512); + algorithmOids.put("MLDSA44-ED25519-SHA512", IANAObjectIdentifiers.id_MLDSA44_Ed25519_SHA512); algorithmOids.put("MLDSA44-ECDSA-P256-SHA256", IANAObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256); algorithmOids.put("MLDSA65-RSA3072-PSS-SHA512", IANAObjectIdentifiers.id_MLDSA65_RSA3072_PSS_SHA512); algorithmOids.put("MLDSA65-RSA3072-PKCS15-SHA512", IANAObjectIdentifiers.id_MLDSA65_RSA3072_PKCS15_SHA512); @@ -23,11 +23,11 @@ class CompositeUtil algorithmOids.put("MLDSA65-RSA4096-PKCS15-SHA512", IANAObjectIdentifiers.id_MLDSA65_RSA4096_PKCS15_SHA512); algorithmOids.put("MLDSA65-ECDSA-P256-SHA512", IANAObjectIdentifiers.id_MLDSA65_ECDSA_P256_SHA512); algorithmOids.put("MLDSA65-ECDSA-P384-SHA512", IANAObjectIdentifiers.id_MLDSA65_ECDSA_P384_SHA512); - algorithmOids.put("MLDSA65-ECDSA-brainpoolP256r1-SHA512", IANAObjectIdentifiers.id_MLDSA65_ECDSA_brainpoolP256r1_SHA512); - algorithmOids.put("MLDSA65-Ed25519-SHA512", IANAObjectIdentifiers.id_MLDSA65_Ed25519_SHA512); + algorithmOids.put("MLDSA65-ECDSA-BRAINPOOLP256R1-SHA512", IANAObjectIdentifiers.id_MLDSA65_ECDSA_brainpoolP256r1_SHA512); + algorithmOids.put("MLDSA65-ED25519-SHA512", IANAObjectIdentifiers.id_MLDSA65_Ed25519_SHA512); algorithmOids.put("MLDSA87-ECDSA-P384-SHA512", IANAObjectIdentifiers.id_MLDSA87_ECDSA_P384_SHA512); - algorithmOids.put("MLDSA87-ECDSA-brainpoolP384r1-SHA512", IANAObjectIdentifiers.id_MLDSA87_ECDSA_brainpoolP384r1_SHA512); - algorithmOids.put("MLDSA87-Ed448-SHAKE256", IANAObjectIdentifiers.id_MLDSA87_Ed448_SHAKE256); + algorithmOids.put("MLDSA87-ECDSA-BRAINPOOLP384R1-SHA512", IANAObjectIdentifiers.id_MLDSA87_ECDSA_brainpoolP384r1_SHA512); + algorithmOids.put("MLDSA87-ED448-SHAKE256", IANAObjectIdentifiers.id_MLDSA87_Ed448_SHAKE256); algorithmOids.put("MLDSA87-RSA4096-PSS-SHA512", IANAObjectIdentifiers.id_MLDSA87_RSA4096_PSS_SHA512); algorithmOids.put("MLDSA87-ECDSA-P521-SHA512", IANAObjectIdentifiers.id_MLDSA87_ECDSA_P521_SHA512); algorithmOids.put("MLDSA87-RSA3072-PSS-SHA512", IANAObjectIdentifiers.id_MLDSA87_RSA3072_PSS_SHA512); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java b/prov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java index 2541e65e0a..7f37be8f6a 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/PKCS12StoreParameter.java @@ -5,6 +5,15 @@ import java.security.KeyStore.LoadStoreParameter; import java.security.KeyStore.ProtectionParameter; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.pkcs.PBKDF2Params; +import org.bouncycastle.asn1.pkcs.PBMAC1Params; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; +import org.bouncycastle.util.Arrays; + /** * LoadStoreParameter to allow for additional config with PKCS12 files. *

    @@ -18,6 +27,123 @@ public class PKCS12StoreParameter private final ProtectionParameter protectionParameter; private final boolean forDEREncoding; private final boolean overwriteFriendlyName; + private final AlgorithmIdentifier macAlgorithm; + + public static class PBMAC1WithPBKDF2Builder + { + private int iterationCount = 16384; + private byte[] salt = null; + private int keySizeinBits = 256; + private ASN1ObjectIdentifier prf = PKCSObjectIdentifiers.id_hmacWithSHA256; + private ASN1ObjectIdentifier mac = PKCSObjectIdentifiers.id_hmacWithSHA512; + + PBMAC1WithPBKDF2Builder() + { + + } + + public PBMAC1WithPBKDF2Builder setIterationCount(int iterationCount) + { + this.iterationCount = iterationCount; + + return this; + } + + public PBMAC1WithPBKDF2Builder setSalt(byte[] salt) + { + this.salt = Arrays.clone(salt); + + return this; + } + + public PBMAC1WithPBKDF2Builder setKeySize(int keySizeinBits) + { + this.keySizeinBits = keySizeinBits; + + return this; + } + + public PBMAC1WithPBKDF2Builder setPrf(ASN1ObjectIdentifier prf) + { + this.prf = prf; + + return this; + } + + public PBMAC1WithPBKDF2Builder setMac(ASN1ObjectIdentifier mac) + { + this.mac = mac; + + return this; + } + + public AlgorithmIdentifier build() + { + if (salt != null) + { + throw new IllegalStateException("salt must be non-null"); + } + + return new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBMAC1, new PBMAC1Params(new AlgorithmIdentifier(PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount, keySizeinBits, new AlgorithmIdentifier(prf))), + new AlgorithmIdentifier(mac))); + } + } + + public static PBMAC1WithPBKDF2Builder pbmac1WithPBKDF2Builder() + { + return new PBMAC1WithPBKDF2Builder(); + } + + public static class Builder + { + private final OutputStream out; + private final ProtectionParameter protectionParameter; + private boolean forDEREncoding = true; + private boolean overwriteFriendlyName = true; + private AlgorithmIdentifier macAlgorithm = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE); + + private Builder(OutputStream out, ProtectionParameter protectionParameter) + { + this.out = out; + this.protectionParameter = protectionParameter; + } + + public Builder setDEREncoding(boolean enable) + { + this.forDEREncoding = enable; + + return this; + } + + public Builder setOverwriteFriendlyName(boolean enable) + { + this.overwriteFriendlyName = enable; + + return this; + } + + public Builder setMacAlgorithm(AlgorithmIdentifier macAlgorithm) + { + this.macAlgorithm = macAlgorithm; + + return this; + } + + public PKCS12StoreParameter build() + { + return new PKCS12StoreParameter(out, protectionParameter, forDEREncoding, overwriteFriendlyName, macAlgorithm); + } + } + + public static Builder builder(OutputStream out, char[] password) + { + return builder(out, new KeyStore.PasswordProtection(password)); + } + + public static Builder builder(OutputStream out, ProtectionParameter protectionParameter) + { + return new Builder(out, protectionParameter); + } public PKCS12StoreParameter(OutputStream out, char[] password) { @@ -33,6 +159,7 @@ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREnc { this(out, new KeyStore.PasswordProtection(password), forDEREncoding, true); } + public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding) { this(out, protectionParameter, forDEREncoding, true); @@ -44,11 +171,17 @@ public PKCS12StoreParameter(OutputStream out, char[] password, boolean forDEREnc } public PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding, boolean overwriteFriendlyName) + { + this(out, protectionParameter, forDEREncoding, overwriteFriendlyName, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)); + } + + private PKCS12StoreParameter(OutputStream out, ProtectionParameter protectionParameter, boolean forDEREncoding, boolean overwriteFriendlyName, AlgorithmIdentifier macAlgorithm) { this.out = out; this.protectionParameter = protectionParameter; this.forDEREncoding = forDEREncoding; this.overwriteFriendlyName = overwriteFriendlyName; + this.macAlgorithm = macAlgorithm; } public OutputStream getOutputStream() @@ -81,4 +214,9 @@ public boolean isOverwriteFriendlyName() { return overwriteFriendlyName; } + + public AlgorithmIdentifier getMacAlgorithm() + { + return macAlgorithm; + } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/GM.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/GM.java index 86c143edc2..292b7b1412 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/GM.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/GM.java @@ -4,6 +4,7 @@ import java.util.Map; import org.bouncycastle.asn1.gm.GMObjectIdentifiers; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; @@ -28,6 +29,10 @@ public Mappings() public void configure(ConfigurableProvider provider) { + provider.addAlgorithm("KeyAgreement.SM2", PREFIX + "GMKeyExchangeSpi$SM2"); + provider.addAlgorithm("KeyAgreement", GMObjectIdentifiers.sm2exchange, PREFIX + "GMKeyExchangeSpi$SM2"); + + // provider.addAlgorithm("Signature.BLAKE2BWITHSM2", PREFIX + "GMSignatureSpi$blake2b512WithSM2"); // provider.addAlgorithm("Alg.Alias.Signature." + GMObjectIdentifiers.sm2sign_with_blake2b512, "BLAKE2BWITHSM2"); // provider.addAlgorithm("Signature.BLAKE2SWITHSM2", PREFIX + "GMSignatureSpi$blake2s256WithSM2"); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java index 4fc74ce683..2c44f309dd 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java @@ -5,6 +5,7 @@ import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.jcajce.util.SpiUtil; public class MLKEM { @@ -51,6 +52,16 @@ public void configure(ConfigurableProvider provider) provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_512, keyFact); provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_768, keyFact); provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_1024, keyFact); + + if (SpiUtil.hasKEM()) + { + // "This algorithm supports keys with ML-KEM-512, ML-KEM-768, and ML-KEM-1024 parameter sets." + provider.addAlgorithm("KEM.ML-KEM", PREFIX + "MLKEMSpi$MLKEM"); + + addKEMAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); + addKEMAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); + addKEMAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); + } } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyFactorySpi.java index c0f7dcd1da..1bf1360fe4 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyFactorySpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/KeyFactorySpi.java @@ -25,7 +25,6 @@ import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; -import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; @@ -56,20 +55,24 @@ public class KeyFactorySpi extends BaseKeyFactorySpi implements AsymmetricKeyInfoConverter { + private static AlgorithmIdentifier createECAlgID(ASN1ObjectIdentifier curveOid) + { + return new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(curveOid)); + } //Specific algorithm identifiers of all component signature algorithms for SubjectPublicKeyInfo. These do not need to be all initialized here but makes the code more readable IMHO. private static final AlgorithmIdentifier mlDsa44 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_ml_dsa_44); private static final AlgorithmIdentifier mlDsa65 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_ml_dsa_65); private static final AlgorithmIdentifier mlDsa87 = new AlgorithmIdentifier(NISTObjectIdentifiers.id_ml_dsa_87); - private static final AlgorithmIdentifier falcon512Identifier = new AlgorithmIdentifier(BCObjectIdentifiers.falcon_512); +// private static final AlgorithmIdentifier falcon512Identifier = new AlgorithmIdentifier(BCObjectIdentifiers.falcon_512); private static final AlgorithmIdentifier ed25519 = new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519); - private static final AlgorithmIdentifier ecDsaP256 = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(SECObjectIdentifiers.secp256r1)); - private static final AlgorithmIdentifier ecDsaBrainpoolP256r1 = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(TeleTrusTObjectIdentifiers.brainpoolP256r1)); - private static final AlgorithmIdentifier rsa = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption); private static final AlgorithmIdentifier ed448 = new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448); - private static final AlgorithmIdentifier ecDsaP384 = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(SECObjectIdentifiers.secp384r1)); - private static final AlgorithmIdentifier ecDsaP521 = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(SECObjectIdentifiers.secp521r1)); - private static final AlgorithmIdentifier ecDsaBrainpoolP384r1 = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, new X962Parameters(TeleTrusTObjectIdentifiers.brainpoolP384r1)); + private static final AlgorithmIdentifier ecDsaP256 = createECAlgID(SECObjectIdentifiers.secp256r1); + private static final AlgorithmIdentifier ecDsaP384 = createECAlgID(SECObjectIdentifiers.secp384r1); + private static final AlgorithmIdentifier ecDsaP521 = createECAlgID(SECObjectIdentifiers.secp521r1); + private static final AlgorithmIdentifier ecDsaBrainpoolP256r1 = createECAlgID(TeleTrusTObjectIdentifiers.brainpoolP256r1); + private static final AlgorithmIdentifier ecDsaBrainpoolP384r1 = createECAlgID(TeleTrusTObjectIdentifiers.brainpoolP384r1); + private static final AlgorithmIdentifier rsa = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption); private static Map pairings = new HashMap(); private static Map componentKeySizes = new HashMap(); @@ -289,7 +292,7 @@ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) try { - seq = DERSequence.getInstance(keyInfo.getPublicKeyData().getBytes()); + seq = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getOctets()); } catch (Exception e) { @@ -299,7 +302,8 @@ public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) if (MiscObjectIdentifiers.id_alg_composite.equals(keyIdentifier) || MiscObjectIdentifiers.id_composite_key.equals(keyIdentifier)) { - ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getBytes()); + // TODO This is redundant with 'seq' calculation above + ASN1Sequence keySeq = ASN1Sequence.getInstance(keyInfo.getPublicKeyData().getOctets()); PublicKey[] pubKeys = new PublicKey[keySeq.size()]; for (int i = 0; i != keySeq.size(); i++) diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java index 447047b1eb..de874e36cf 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java @@ -496,7 +496,7 @@ public int engineDoFinal( * Classes that inherit from us */ - static public class IES + public static class IES extends IESCipher { public IES() @@ -507,7 +507,7 @@ public IES() } } - static public class IESwithDESedeCBC + public static class IESwithDESedeCBC extends IESCipher { public IESwithDESedeCBC() @@ -519,7 +519,7 @@ public IESwithDESedeCBC() } } - static public class IESwithAESCBC + public static class IESwithAESCBC extends IESCipher { public IESwithAESCBC() diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/KeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/KeyPairGeneratorSpi.java index d776a58bc6..f0e68d0796 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/KeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dstu/KeyPairGeneratorSpi.java @@ -117,8 +117,19 @@ else if (params instanceof ECGenParameterSpec || params instanceof ECNamedCurveG curveName = ((ECNamedCurveGenParameterSpec)params).getName(); } - //ECDomainParameters ecP = ECGOST3410NamedCurves.getByName(curveName); - ECDomainParameters ecP = DSTU4145NamedCurves.getByOID(new ASN1ObjectIdentifier(curveName)); + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(curveName); + + ECDomainParameters ecP; + if (oid != null) + { + ecP = DSTU4145NamedCurves.getByOID(oid); + } + else + { + // TODO Add curve names to DSTU4145NamedCurves registry and support getByName + throw new InvalidAlgorithmParameterException("non-OID curve name not supported: " + curveName); + } + if (ecP == null) { throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java index ec97fe1758..45b65975b0 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java @@ -54,7 +54,7 @@ static X9ECParameters getDomainParametersFromName(String curveName, ProviderConf curveName = curveName.substring(spacePos + 1); } - ASN1ObjectIdentifier oid = getOID(curveName); + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(curveName); if (null == oid) { return ECUtil.getNamedCurveByName(curveName); @@ -107,20 +107,4 @@ else if (ecSpec == null) return params; } - - private static ASN1ObjectIdentifier getOID(String curveName) - { - char firstChar = curveName.charAt(0); - if (firstChar >= '0' && firstChar <= '2') - { - try - { - return new ASN1ObjectIdentifier(curveName); - } - catch (Exception e) - { - } - } - return null; - } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyExchangeSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyExchangeSpi.java new file mode 100644 index 0000000000..d5f308c05f --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyExchangeSpi.java @@ -0,0 +1,110 @@ +package org.bouncycastle.jcajce.provider.asymmetric.ec; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.crypto.agreement.SM2KeyExchange; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.crypto.params.ParametersWithID; +import org.bouncycastle.crypto.params.SM2KeyExchangePrivateParameters; +import org.bouncycastle.crypto.params.SM2KeyExchangePublicParameters; +import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi; +import org.bouncycastle.jcajce.spec.SM2KeyExchangeSpec; +import org.bouncycastle.util.Arrays; + + +public class GMKeyExchangeSpi + extends BaseAgreementSpi +{ + private final String kaAlgorithm; + private final SM2KeyExchange engine; + private SM2KeyExchangeSpec spec; + private byte[] result; + + protected GMKeyExchangeSpi(String kaAlgorithm) + { + super(kaAlgorithm, null); + + this.kaAlgorithm = kaAlgorithm; + this.engine = new SM2KeyExchange(); + } + + protected Key engineDoPhase( + Key key, + boolean lastPhase) + throws InvalidKeyException, IllegalStateException + { + if (spec == null) + { + throw new IllegalStateException(kaAlgorithm + " not initialised."); + } + + if (!lastPhase) + { + throw new IllegalStateException(kaAlgorithm + " can only be between two parties."); + } + + if (!(key instanceof BCECPublicKey)) + { + throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + + getSimpleName(BCECPublicKey.class) + " for doPhase"); + } + ECPublicKeyParameters staticKey = (ECPublicKeyParameters)ECUtils.generatePublicKeyParameter((PublicKey)key); + ECPublicKeyParameters ephemeralKey = (ECPublicKeyParameters)ECUtils.generatePublicKeyParameter(spec.getOtherPartyEphemeralKey()); + + ParametersWithID parameters = new ParametersWithID(new SM2KeyExchangePublicParameters(staticKey, ephemeralKey), + spec.getOtherPartyId()); + + result = engine.calculateKey(128, parameters); + + return null; + } + + protected void doInitFromKey(Key key, AlgorithmParameterSpec parameterSpec, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + if (parameterSpec != null && !(parameterSpec instanceof SM2KeyExchangeSpec)) + { + throw new InvalidAlgorithmParameterException("No algorithm parameters supported"); + } + + if (!(key instanceof PrivateKey)) + { + throw new InvalidKeyException(kaAlgorithm + " key agreement requires " + + getSimpleName(BCECPrivateKey.class) + " for initialisation"); + } + spec = (SM2KeyExchangeSpec)parameterSpec; + + ECPrivateKeyParameters staticKey = (ECPrivateKeyParameters)ECUtils.generatePrivateKeyParameter((PrivateKey)key); + ECPrivateKeyParameters ephemeralKey = (ECPrivateKeyParameters)ECUtils.generatePrivateKeyParameter(spec.getEphemeralPrivateKey()); + ParametersWithID parameters = new ParametersWithID(new SM2KeyExchangePrivateParameters(spec.isInitiator(), staticKey, ephemeralKey), spec.getId()); + engine.init(parameters); + } + + private static String getSimpleName(Class clazz) + { + String fullName = clazz.getName(); + + return fullName.substring(fullName.lastIndexOf('.') + 1); + } + + protected byte[] doCalcSecret() + { + return Arrays.clone(result); + } + + public static class SM2 + extends GMKeyExchangeSpi + { + public SM2() + { + super("SM2"); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java index e1d509a186..28daab22a7 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java @@ -48,7 +48,7 @@ public static class BaseSM2 String algorithm; ProviderConfiguration configuration; - static private Hashtable ecParameters; + private static final Hashtable ecParameters; static { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java index 7f729ffa74..c85218a4d9 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java @@ -48,7 +48,7 @@ public static class EC String algorithm; ProviderConfiguration configuration; - static private Hashtable ecParameters; + private static final Hashtable ecParameters; static { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java index ebbc2345f2..92a6864afd 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java @@ -59,13 +59,13 @@ protected byte[] engineGetEncoded() { v.add(new DERTaggedObject(false, 1, new DEROctetString(currentSpec.getEncodingV()))); } - v.add(new ASN1Integer(currentSpec.getMacKeySize())); + v.add(ASN1Integer.valueOf(currentSpec.getMacKeySize())); byte[] currentSpecNonce = currentSpec.getNonce(); if (currentSpecNonce != null) { ASN1EncodableVector cV = new ASN1EncodableVector(); - cV.add(new ASN1Integer(currentSpec.getCipherKeySize())); + cV.add(ASN1Integer.valueOf(currentSpec.getCipherKeySize())); cV.add(new DEROctetString(currentSpecNonce)); v.add(new DERSequence(cV)); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPrivateKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPrivateKey.java index d9dd721c5f..9df1acc9fd 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPrivateKey.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/BCMLKEMPrivateKey.java @@ -130,11 +130,11 @@ public MLKEMPrivateKey getPrivateKey(boolean preferSeedOnly) byte[] seed = params.getSeed(); if (seed != null) { - return new BCMLKEMPrivateKey(this.params.getParametersWithFormat(MLDSAPrivateKeyParameters.SEED_ONLY)); + return new BCMLKEMPrivateKey(this.params.withPreferredFormat(MLDSAPrivateKeyParameters.SEED_ONLY)); } } - return new BCMLKEMPrivateKey(this.params.getParametersWithFormat(MLDSAPrivateKeyParameters.EXPANDED_KEY)); + return new BCMLKEMPrivateKey(this.params.withPreferredFormat(MLDSAPrivateKeyParameters.EXPANDED_KEY)); } public MLKEMParameterSpec getParameterSpec() diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java index 2218cf1894..52c2794c70 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java @@ -32,46 +32,46 @@ import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; -class MLKEMCipherSpi +public class MLKEMCipherSpi extends CipherSpi { + private final MLKEMParameters mlkemParameters; private final String algorithmName; + private MLKEMGenerator kemGen; private KTSParameterSpec kemParameterSpec; private BCMLKEMPublicKey wrapKey; private BCMLKEMPrivateKey unwrapKey; private AlgorithmParameters engineParams; - private MLKEMParameters mlkemParamters; - MLKEMCipherSpi(String algorithmName) + public MLKEMCipherSpi(String algorithmName) { + this.mlkemParameters = null; this.algorithmName = algorithmName; - this.mlkemParamters = null; } - MLKEMCipherSpi(MLKEMParameters kyberParameters) + public MLKEMCipherSpi(MLKEMParameters mlkemParameters) { - this.mlkemParamters = kyberParameters; - this.algorithmName = kyberParameters.getName(); + this.mlkemParameters = mlkemParameters; + this.algorithmName = mlkemParameters.getName(); } @Override protected void engineSetMode(String mode) - throws NoSuchAlgorithmException + throws NoSuchAlgorithmException { throw new NoSuchAlgorithmException("Cannot support mode " + mode); } @Override protected void engineSetPadding(String padding) - throws NoSuchPaddingException + throws NoSuchPaddingException { throw new NoSuchPaddingException("Padding " + padding + " unknown"); } - protected int engineGetKeySize( - Key key) + protected int engineGetKeySize(Key key) { return 2048; // TODO //throw new IllegalArgumentException("not an valid key!"); @@ -153,7 +153,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (key instanceof BCMLKEMPublicKey) { wrapKey = (BCMLKEMPublicKey)key; - kemGen = new MLKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + kemGen = new MLKEMGenerator(random); } else { @@ -176,9 +176,9 @@ else if (opmode == Cipher.UNWRAP_MODE) throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping"); } - if (mlkemParamters != null) + if (mlkemParameters != null) { - String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParamters.getName()).getName(); + String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName(); if (!canonicalAlgName.equals(key.getAlgorithm())) { throw new InvalidKeyException("cipher locked to " + canonicalAlgName); @@ -256,11 +256,14 @@ protected byte[] engineWrap( byte[] keyToWrap = key.getEncoded(); - byte[] rv = Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); - - Arrays.clear(keyToWrap); - - return rv; + try + { + return Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); + } + finally + { + Arrays.clear(keyToWrap); + } } catch (IllegalArgumentException e) { @@ -277,7 +280,7 @@ protected byte[] engineWrap( } catch (DestroyFailedException e) { - throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + // ignore } } } @@ -293,6 +296,7 @@ protected Key engineUnwrap( { throw new InvalidKeyException("only SECRET_KEY supported"); } + byte[] secret = null; try { @@ -318,18 +322,14 @@ protected Key engineUnwrap( } finally { - if (secret != null) - { - Arrays.clear(secret); - } + Arrays.clear(secret); } } public static class Base - extends MLKEMCipherSpi + extends MLKEMCipherSpi { public Base() - throws NoSuchAlgorithmException { super("MLKEM"); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java index eb3a50c1ca..76dc03bd5d 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java @@ -21,21 +21,22 @@ import org.bouncycastle.util.Arrays; public class MLKEMKeyGeneratorSpi - extends KeyGeneratorSpi + extends KeyGeneratorSpi { + private final MLKEMParameters mlkemParameters; + private KEMGenerateSpec genSpec; private SecureRandom random; private KEMExtractSpec extSpec; - private MLKEMParameters kyberParameters; public MLKEMKeyGeneratorSpi() { this(null); } - protected MLKEMKeyGeneratorSpi(MLKEMParameters kyberParameters) + protected MLKEMKeyGeneratorSpi(MLKEMParameters mlkemParameters) { - this.kyberParameters = kyberParameters; + this.mlkemParameters = mlkemParameters; } protected void engineInit(SecureRandom secureRandom) @@ -51,9 +52,9 @@ protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec, SecureR { this.genSpec = (KEMGenerateSpec)algorithmParameterSpec; this.extSpec = null; - if (kyberParameters != null) + if (mlkemParameters != null) { - String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName(); + String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName(); if (!canonicalAlgName.equals(genSpec.getPublicKey().getAlgorithm())) { throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); @@ -64,9 +65,9 @@ else if (algorithmParameterSpec instanceof KEMExtractSpec) { this.genSpec = null; this.extSpec = (KEMExtractSpec)algorithmParameterSpec; - if (kyberParameters != null) + if (mlkemParameters != null) { - String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName(); + String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName(); if (!canonicalAlgName.equals(extSpec.getPrivateKey().getAlgorithm())) { throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); @@ -93,24 +94,26 @@ protected SecretKey engineGenerateKey() SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(pubKey.getKeyParams()); - byte[] sharedSecret = secEnc.getSecret(); - - byte[] secret = KdfUtil.makeKeyBytes(genSpec, sharedSecret); - - Arrays.clear(sharedSecret); - - SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); + byte[] kemSecret = secEnc.getSecret(); + byte[] kdfSecret = KdfUtil.makeKeyBytes(genSpec, kemSecret); try { - secEnc.destroy(); + SecretKeySpec secretKey = new SecretKeySpec(kdfSecret, genSpec.getKeyAlgorithmName()); + + return new SecretKeyWithEncapsulation(secretKey, secEnc.getEncapsulation()); } - catch (DestroyFailedException e) + finally { - throw new IllegalStateException("key cleanup failed"); + try + { + secEnc.destroy(); + } + catch (DestroyFailedException e) + { + // ignore + } } - - return rv; } else { @@ -118,16 +121,21 @@ protected SecretKey engineGenerateKey() MLKEMExtractor kemExt = new MLKEMExtractor(privKey.getKeyParams()); byte[] encapsulation = extSpec.getEncapsulation(); - byte[] sharedSecret = kemExt.extractSecret(encapsulation); - byte[] secret = KdfUtil.makeKeyBytes(extSpec, sharedSecret); - - Arrays.clear(sharedSecret); - SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, extSpec.getKeyAlgorithmName()), encapsulation); + byte[] kemSecret = kemExt.extractSecret(encapsulation); + byte[] kdfSecret = KdfUtil.makeKeyBytes(extSpec, kemSecret); - Arrays.clear(secret); + try + { + SecretKeySpec secretKey = new SecretKeySpec(kdfSecret, extSpec.getKeyAlgorithmName()); - return rv; + // TODO Why do we return ...WithEncapsulation?? + return new SecretKeyWithEncapsulation(secretKey, encapsulation); + } + finally + { + Arrays.clear(kdfSecret); + } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java index baa4ed94be..3696fc840f 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java @@ -194,7 +194,8 @@ protected byte[] engineGetEncoded() AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(DigestFactory.getOID(mgfSpec.getDigestAlgorithm()), DERNull.INSTANCE)); - RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField())); + RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, + ASN1Integer.valueOf(pssSpec.getSaltLength()), ASN1Integer.valueOf(pssSpec.getTrailerField())); return pssP.getEncoded("DER"); } @@ -202,7 +203,8 @@ protected byte[] engineGetEncoded() { AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier( pssSpec.getMGFAlgorithm().equals("SHAKE128") ? NISTObjectIdentifiers.id_shake128 : NISTObjectIdentifiers.id_shake256); - RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, new ASN1Integer(pssSpec.getSaltLength()), new ASN1Integer(pssSpec.getTrailerField())); + RSASSAPSSparams pssP = new RSASSAPSSparams(hashAlgorithm, maskGenAlgorithm, + ASN1Integer.valueOf(pssSpec.getSaltLength()), ASN1Integer.valueOf(pssSpec.getTrailerField())); return pssP.getEncoded("DER"); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/HashSignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/HashSignatureSpi.java index 0e6b42c197..65d71a74b2 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/HashSignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/HashSignatureSpi.java @@ -118,7 +118,7 @@ protected void reInitialize(boolean forSigning, CipherParameters params) signer.init(forSigning, params); } - static public class Direct + public static class Direct extends HashSignatureSpi { public Direct() diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SignatureSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SignatureSpi.java index 2a8ea4a538..b0d8cb3b87 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SignatureSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/slhdsa/SignatureSpi.java @@ -123,8 +123,8 @@ protected void reInitialize(boolean forSigning, CipherParameters params) bOut.reset(); } - - static public class Direct + + public static class Direct extends SignatureSpi { public Direct() diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java index cd9699033d..08a8df9669 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java @@ -339,12 +339,8 @@ private byte[] getSharedSecretBytes(byte[] secret, String oidAlgorithm, int keyS { throw new NoSuchAlgorithmException("algorithm OID is null"); } - ASN1ObjectIdentifier oid; - try - { - oid = new ASN1ObjectIdentifier(oidAlgorithm); - } - catch (IllegalArgumentException e) + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(oidAlgorithm); + if (oid == null) { throw new NoSuchAlgorithmException("no OID for algorithm: " + oidAlgorithm); } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java index 0e51a76717..dbf983881f 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java @@ -330,7 +330,7 @@ public static ASN1ObjectIdentifier getNamedCurveOid( curveName = curveName.substring(spacePos + 1); } - ASN1ObjectIdentifier oid = getOID(curveName); + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(curveName); if (null != oid) { return oid; @@ -437,20 +437,4 @@ public static String getNameFrom(final AlgorithmParameterSpec paramSpec) { return SpecUtil.getNameFrom(paramSpec); } - - private static ASN1ObjectIdentifier getOID(String curveName) - { - char firstChar = curveName.charAt(0); - if (firstChar >= '0' && firstChar <= '2') - { - try - { - return new ASN1ObjectIdentifier(curveName); - } - catch (Exception e) - { - } - } - return null; - } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java index 1664a9cf87..6a091f78cf 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PKIXCertPath.java @@ -290,7 +290,7 @@ else if (encoding.equalsIgnoreCase("PKCS7")) } SignedData sd = new SignedData( - new ASN1Integer(1), + ASN1Integer.ONE, new DERSet(), encInfo, new DERSet(v), diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SM4.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SM4.java index e416a02817..2d790ef520 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SM4.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SM4.java @@ -5,21 +5,27 @@ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; +import org.bouncycastle.asn1.gm.GMObjectIdentifiers; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherKeyGenerator; import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.engines.RFC3394WrapEngine; +import org.bouncycastle.crypto.engines.RFC5649WrapEngine; import org.bouncycastle.crypto.engines.SM4Engine; import org.bouncycastle.crypto.generators.Poly1305KeyGenerator; import org.bouncycastle.crypto.macs.CMac; import org.bouncycastle.crypto.macs.GMac; import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.internal.asn1.ntt.NTTObjectIdentifiers; import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator; import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac; +import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher; import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider; import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters; @@ -89,6 +95,24 @@ public Poly1305KeyGen() } } + public static class Wrap + extends BaseWrapCipher + { + public Wrap() + { + super(new SM4WrapEngine()); + } + } + + public static class WrapPad + extends BaseWrapCipher + { + public WrapPad() + { + super(new SM4WrapPadEngine()); + } + } + public static class AlgParamGen extends BaseAlgorithmParameterGenerator { @@ -158,6 +182,29 @@ public void configure(ConfigurableProvider provider) addCMacAlgorithm(provider, "SM4", PREFIX + "$CMAC", PREFIX + "$KeyGen"); addGMacAlgorithm(provider, "SM4", PREFIX + "$GMAC", PREFIX + "$KeyGen"); addPoly1305Algorithm(provider, "SM4", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen"); + + provider.addAlgorithm("Cipher.SM4WRAP", PREFIX + "$Wrap"); + provider.addAlgorithm("Cipher.SM4WRAPPAD", PREFIX + "$WrapPad"); + provider.addAlgorithm("Cipher", GMObjectIdentifiers.sms4_wrap, PREFIX + "$Wrap"); + provider.addAlgorithm("Cipher", GMObjectIdentifiers.sms4_wrap_pad, PREFIX + "$WrapPad"); + } + } + + private static class SM4WrapEngine + extends RFC3394WrapEngine + { + public SM4WrapEngine() + { + super(new SM4Engine()); + } + } + + private static class SM4WrapPadEngine + extends RFC5649WrapEngine + { + public SM4WrapPadEngine() + { + super(new SM4Engine()); } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index 66d49fb19e..caa4bfb22b 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -1328,7 +1328,7 @@ private boolean isAEADModeName( * The ciphers that inherit from us. */ - static private interface GenericBlockCipher + private static interface GenericBlockCipher { public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java index 02a691c6c4..4c60a4d9d7 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java @@ -59,9 +59,7 @@ public interface PBE */ static class Util { - static private PBEParametersGenerator makePBEGenerator( - int type, - int hash) + private static PBEParametersGenerator makePBEGenerator(int type, int hash) { PBEParametersGenerator generator; diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java index 88810d9acc..adcfde06b9 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/util/AsymmetricAlgorithmProvider.java @@ -147,6 +147,20 @@ protected void addCipherAlgorithm( } } + protected void addKEMAlgorithm( + ConfigurableProvider provider, + String algorithm, + String className, + ASN1ObjectIdentifier oid) + { + provider.addAlgorithm("KEM." + algorithm, className); + if (oid != null) + { + provider.addAlgorithm("Alg.Alias.KEM." + oid, algorithm); + provider.addAlgorithm("Alg.Alias.KEM.OID." + oid, algorithm); + } + } + protected void registerKeyFactoryOid(ConfigurableProvider provider, ASN1ObjectIdentifier oid, String name, AsymmetricKeyInfoConverter keyFactory) { provider.addAlgorithm("Alg.Alias.KeyFactory." + oid, name); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/spec/SM2KeyExchangeSpec.java b/prov/src/main/java/org/bouncycastle/jcajce/spec/SM2KeyExchangeSpec.java new file mode 100644 index 0000000000..5e6e169d40 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/spec/SM2KeyExchangeSpec.java @@ -0,0 +1,53 @@ +package org.bouncycastle.jcajce.spec; + +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.AlgorithmParameterSpec; + +import org.bouncycastle.util.Arrays; + +public class SM2KeyExchangeSpec + implements AlgorithmParameterSpec +{ + private final PrivateKey ephemeralPrivateKey; + private final PublicKey otherPartyEphemeralKey; + private final byte[] id; + private final byte[] otherPartyId; + private final boolean initiator; + + public SM2KeyExchangeSpec(boolean initiator, PrivateKey ephemeralPrivateKey, + PublicKey otherPartyEphemeralKey, byte[] id, byte[] otherPartyId) + { + this.initiator = initiator; + this.ephemeralPrivateKey = ephemeralPrivateKey; + this.otherPartyEphemeralKey = otherPartyEphemeralKey; + this.id = Arrays.clone(id); + this.otherPartyId = Arrays.clone(otherPartyId); + } + + public PrivateKey getEphemeralPrivateKey() + { + return ephemeralPrivateKey; + } + + public PublicKey getOtherPartyEphemeralKey() + { + return otherPartyEphemeralKey; + } + + public byte[] getId() + { + return Arrays.clone(id); + } + + public byte[] getOtherPartyId() + { + return Arrays.clone(otherPartyId); + } + + public boolean isInitiator() + { + return initiator; + } +} + diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java b/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java index 214f86393b..1cc00c195b 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java @@ -40,6 +40,11 @@ public NamedJcaJceHelper(String providerName) this.providerName = providerName; } + public String getProviderName() + { + return providerName; + } + public Cipher createCipher( String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException, NoSuchProviderException diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java b/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java index b9a28fa5e0..fb27157be3 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java @@ -40,6 +40,11 @@ public ProviderJcaJceHelper(Provider provider) this.provider = provider; } + public Provider getProvider() + { + return provider; + } + public Cipher createCipher( String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException diff --git a/prov/src/main/java/org/bouncycastle/jcajce/util/SpiUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/util/SpiUtil.java new file mode 100644 index 0000000000..97af2d666c --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/jcajce/util/SpiUtil.java @@ -0,0 +1,14 @@ +package org.bouncycastle.jcajce.util; + +public abstract class SpiUtil +{ + public static boolean hasKDF() + { + return false; + } + + public static boolean hasKEM() + { + return false; + } +} diff --git a/prov/src/main/java/org/bouncycastle/jce/ECGOST3410NamedCurveTable.java b/prov/src/main/java/org/bouncycastle/jce/ECGOST3410NamedCurveTable.java index a70aa3bd7b..4a552b7137 100644 --- a/prov/src/main/java/org/bouncycastle/jce/ECGOST3410NamedCurveTable.java +++ b/prov/src/main/java/org/bouncycastle/jce/ECGOST3410NamedCurveTable.java @@ -25,13 +25,10 @@ public static ECNamedCurveParameterSpec getParameterSpec( X9ECParameters ecP = ECGOST3410NamedCurves.getByNameX9(name); if (ecP == null) { - try + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(name); + if (oid != null) { - ecP = ECGOST3410NamedCurves.getByOIDX9(new ASN1ObjectIdentifier(name)); - } - catch (IllegalArgumentException e) - { - return null; // not an oid. + ecP = ECGOST3410NamedCurves.getByOIDX9(oid); } } diff --git a/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java b/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java index 1165dc5db0..4e25adbc29 100644 --- a/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java +++ b/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java @@ -21,15 +21,7 @@ public class ECNamedCurveTable public static ECNamedCurveParameterSpec getParameterSpec( String name) { - ASN1ObjectIdentifier oid; - try - { - oid = possibleOID(name) ? new ASN1ObjectIdentifier(name) : null; - } - catch (IllegalArgumentException e) - { - oid = null; - } + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(name); X9ECParameters ecP; if (oid != null) @@ -76,21 +68,4 @@ public static Enumeration getNames() { return org.bouncycastle.asn1.x9.ECNamedCurveTable.getNames(); } - - private static boolean possibleOID( - String identifier) - { - if (identifier.length() < 3 || identifier.charAt(1) != '.') - { - return false; - } - - char first = identifier.charAt(0); - if (first < '0' || first > '2') - { - return false; - } - - return true; - } } diff --git a/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java b/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java index db79c9eb7d..33a0f3e70a 100644 --- a/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java +++ b/prov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java @@ -199,7 +199,7 @@ private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), - new ASN1Integer(saltSize), + ASN1Integer.valueOf(saltSize), RSASSAPSSparams.DEFAULT_TRAILER_FIELD); } @@ -311,11 +311,8 @@ public PKCS10CertificationRequest( if (sigOID == null) { - try - { - sigOID = new ASN1ObjectIdentifier(algorithmName); - } - catch (Exception e) + sigOID = ASN1ObjectIdentifier.tryFromID(algorithmName); + if (sigOID == null) { throw new IllegalArgumentException("Unknown signature type requested"); } diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/BrokenKDF2BytesGenerator.java b/prov/src/main/java/org/bouncycastle/jce/provider/BrokenKDF2BytesGenerator.java deleted file mode 100644 index 0f328f6078..0000000000 --- a/prov/src/main/java/org/bouncycastle/jce/provider/BrokenKDF2BytesGenerator.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.bouncycastle.jce.provider; - -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.DerivationFunction; -import org.bouncycastle.crypto.DerivationParameters; -import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.OutputLengthException; -import org.bouncycastle.crypto.params.KDFParameters; - -/** - * Generator for PBE derived keys and ivs as defined by IEEE P1363a - *
    - * This implementation is based on draft 9 of IEEE P1363a. Note: - * as this is still a draft the output of this generator may change, don't - * use it for anything that might be subject to long term storage. - */ -public class BrokenKDF2BytesGenerator - implements DerivationFunction -{ - private Digest digest; - private byte[] shared; - private byte[] iv; - - /** - * Construct a KDF2 Parameters generator. Generates key material - * according to IEEE P1363a - if you want orthodox results you should - * use a digest specified in the standard. - *

    - * Note: IEEE P1363a standard is still a draft standard, if the standard - * changes this function, the output of this function will change as well. - * Don't use this routine for anything subject to long term storage. - * - * @param digest the digest to be used as the source of derived keys. - */ - public BrokenKDF2BytesGenerator( - Digest digest) - { - this.digest = digest; - } - - public void init( - DerivationParameters param) - { - if (!(param instanceof KDFParameters)) - { - throw new IllegalArgumentException("KDF parameters required for generator"); - } - - KDFParameters p = (KDFParameters)param; - - shared = p.getSharedSecret(); - iv = p.getIV(); - } - - /** - * return the underlying digest. - */ - public Digest getDigest() - { - return digest; - } - - /** - * fill len bytes of the output buffer with bytes generated from - * the derivation function. - * - * @throws IllegalArgumentException if the size of the request will cause an overflow. - * @throws DataLengthException if the out buffer is too small. - */ - public int generateBytes( - byte[] out, - int outOff, - int len) - throws DataLengthException, IllegalArgumentException - { - if ((out.length - len) < outOff) - { - throw new OutputLengthException("output buffer too small"); - } - - long oBits = len * 8L; - - // - // this is at odds with the standard implementation, the - // maximum value should be hBits * (2^32 - 1) where hBits - // is the digest output size in bits. We can't have an - // array with a long index at the moment... - // - if (oBits > (digest.getDigestSize() * 8L * (1L<<32 - 1))) - { - throw new IllegalArgumentException("Output length too large"); - } - - int cThreshold = (int)(oBits / digest.getDigestSize()); - - byte[] dig = null; - - dig = new byte[digest.getDigestSize()]; - - for (int counter = 1; counter <= cThreshold; counter++) - { - digest.update(shared, 0, shared.length); - - digest.update((byte)(counter & 0xff)); - digest.update((byte)((counter >> 8) & 0xff)); - digest.update((byte)((counter >> 16) & 0xff)); - digest.update((byte)((counter >> 24) & 0xff)); - - digest.update(iv, 0, iv.length); - - digest.doFinal(dig, 0); - - if ((len - outOff) > dig.length) - { - System.arraycopy(dig, 0, out, outOff, dig.length); - outOff += dig.length; - } - else - { - System.arraycopy(dig, 0, out, outOff, len - outOff); - } - } - - digest.reset(); - - return len; - } -} diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/BrokenPBE.java b/prov/src/main/java/org/bouncycastle/jce/provider/BrokenPBE.java index 509e76fc95..5495d89202 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/BrokenPBE.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/BrokenPBE.java @@ -267,8 +267,7 @@ static class Util * * @param bytes the byte array to set the parity on. */ - static private void setOddParity( - byte[] bytes) + private static void setOddParity(byte[] bytes) { for (int i = 0; i < bytes.length; i++) { @@ -284,9 +283,7 @@ static private void setOddParity( } } - static private PBEParametersGenerator makePBEGenerator( - int type, - int hash) + private static PBEParametersGenerator makePBEGenerator(int type, int hash) { PBEParametersGenerator generator; diff --git a/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java b/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java index 5789fd1714..91e4150afc 100644 --- a/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java +++ b/prov/src/main/java/org/bouncycastle/jce/provider/X509LDAPCertStoreSpi.java @@ -34,6 +34,7 @@ import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.x509.CertificatePair; import org.bouncycastle.jce.X509LDAPCertStoreParameters; +import org.bouncycastle.ldap.LDAPUtils; import org.bouncycastle.util.Strings; /** @@ -50,26 +51,6 @@ public class X509LDAPCertStoreSpi extends CertStoreSpi { - private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1]; - - static - { - // Filter encoding table ------------------------------------- - - // fill with char itself - for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) - { - FILTER_ESCAPE_TABLE[c] = String.valueOf(c); - } - - // escapes (RFC2254) - FILTER_ESCAPE_TABLE['*'] = "\\2a"; - FILTER_ESCAPE_TABLE['('] = "\\28"; - FILTER_ESCAPE_TABLE[')'] = "\\29"; - FILTER_ESCAPE_TABLE['\\'] = "\\5c"; - FILTER_ESCAPE_TABLE[0] = "\\00"; - } - /** * Initial Context Factory. */ @@ -124,42 +105,6 @@ private DirContext connectLDAP() return ctx; } - private String parseDN(String subject, String subjectAttributeName) - { - String temp = subject; - int begin = Strings.toLowerCase(temp).indexOf(Strings.toLowerCase(subjectAttributeName)); - temp = temp.substring(begin + subjectAttributeName.length()); - int end = temp.indexOf(','); - if (end == -1) - { - end = temp.length(); - } - while (temp.charAt(end - 1) == '\\') - { - end = temp.indexOf(',', end + 1); - if (end == -1) - { - end = temp.length(); - } - } - temp = temp.substring(0, end); - begin = temp.indexOf('='); - temp = temp.substring(begin + 1); - if (temp.charAt(0) == ' ') - { - temp = temp.substring(1); - } - if (temp.startsWith("\"")) - { - temp = temp.substring(1); - } - if (temp.endsWith("\"")) - { - temp = temp.substring(0, temp.length() - 1); - } - return filterEncode(temp); - } - public Collection engineGetCertificates(CertSelector selector) throws CertStoreException { @@ -277,7 +222,7 @@ private Set certSubjectSerialSearch(X509CertSelector xselector, subject = xselector.getSubjectAsString(); } } - String attrValue = parseDN(subject, subjectAttributeName); + String attrValue = LDAPUtils.parseDN(subject, subjectAttributeName); set.addAll(search(attrName, "*" + attrValue + "*", attrs)); if (serial != null && params.getSearchForSerialNumberIn() != null) @@ -374,13 +319,13 @@ public Collection engineGetCRLs(CRLSelector selector) { String issuerAttributeName = params .getCertificateRevocationListIssuerAttributeName(); - attrValue = parseDN((String)o, issuerAttributeName); + attrValue = LDAPUtils.parseDN((String)o, issuerAttributeName); } else { String issuerAttributeName = params .getCertificateRevocationListIssuerAttributeName(); - attrValue = parseDN(new X500Principal((byte[])o) + attrValue = LDAPUtils.parseDN(new X500Principal((byte[])o) .getName("RFC1779"), issuerAttributeName); } set.addAll(search(attrName, "*" + attrValue + "*", attrs)); @@ -415,43 +360,7 @@ public Collection engineGetCRLs(CRLSelector selector) return crlSet; } - - /** - * Escape a value for use in a filter. - * - * @param value the value to escape. - * @return a properly escaped representation of the supplied value. - */ - private String filterEncode(String value) - { - if (value == null) - { - return null; - } - - // make buffer roomy - StringBuilder encodedValue = new StringBuilder(value.length() * 2); - - int length = value.length(); - - for (int i = 0; i < length; i++) - { - char c = value.charAt(i); - - if (c < FILTER_ESCAPE_TABLE.length) - { - encodedValue.append(FILTER_ESCAPE_TABLE[c]); - } - else - { - // default: add the char - encodedValue.append(c); - } - } - - return encodedValue.toString(); - } - + /** * Returns a Set of byte arrays with the certificate or CRL encodings. * diff --git a/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java b/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java index ba2bd01965..c5ddd2b989 100644 --- a/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jce/spec/GOST3410ParameterSpec.java @@ -25,22 +25,22 @@ public GOST3410ParameterSpec( String digestParamSetOID, String encryptionParamSetOID) { - GOST3410ParamSetParameters ecP = null; - - try - { - ecP = GOST3410NamedParameters.getByOID(new ASN1ObjectIdentifier(keyParamSetID)); - } - catch (IllegalArgumentException e) + ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.tryFromID(keyParamSetID); + if (oid == null) { - ASN1ObjectIdentifier oid = GOST3410NamedParameters.getOID(keyParamSetID); + oid = GOST3410NamedParameters.getOID(keyParamSetID); if (oid != null) { keyParamSetID = oid.getId(); - ecP = GOST3410NamedParameters.getByOID(oid); } } - + + GOST3410ParamSetParameters ecP = null; + if (oid != null) + { + ecP = GOST3410NamedParameters.getByOID(oid); + } + if (ecP == null) { throw new IllegalArgumentException("no key parameter set for passed in name/OID."); diff --git a/prov/src/main/java/org/bouncycastle/ldap/LDAPUtils.java b/prov/src/main/java/org/bouncycastle/ldap/LDAPUtils.java new file mode 100644 index 0000000000..2d6bb3bc78 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/ldap/LDAPUtils.java @@ -0,0 +1,112 @@ +package org.bouncycastle.ldap; + +import org.bouncycastle.util.Strings; + +/** + * General utility methods for assisting with preparation of LDAP queries. + */ +public class LDAPUtils +{ + private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1]; + + static + { + // Filter encoding table ------------------------------------- + + // fill with char itself + for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) + { + FILTER_ESCAPE_TABLE[c] = String.valueOf(c); + } + + // escapes (RFC2254) + FILTER_ESCAPE_TABLE['*'] = "\\2a"; + FILTER_ESCAPE_TABLE['('] = "\\28"; + FILTER_ESCAPE_TABLE[')'] = "\\29"; + FILTER_ESCAPE_TABLE['\\'] = "\\5c"; + FILTER_ESCAPE_TABLE[0] = "\\00"; + } + + /** + * Parse out the contents of a particular subject attribute name from the string form of an X.500 DN. + * + * @param subject string form of an X.500 DN. + * @param subjectAttributeName the RDN attribute name of interest. + * @return an escaped string suitable for use in an LDAP query. + */ + public static String parseDN(String subject, String subjectAttributeName) + { + String temp = subject; + int begin = Strings.toLowerCase(temp).indexOf(Strings.toLowerCase(subjectAttributeName)); + if (begin == -1) + { + return ""; + } + temp = temp.substring(begin + subjectAttributeName.length()); + int end = temp.indexOf(','); + if (end == -1) + { + end = temp.length(); + } + while (temp.charAt(end - 1) == '\\') + { + end = temp.indexOf(',', end + 1); + if (end == -1) + { + end = temp.length(); + } + } + temp = temp.substring(0, end); + begin = temp.indexOf('='); + temp = temp.substring(begin + 1); + if (temp.charAt(0) == ' ') + { + temp = temp.substring(1); + } + if (temp.startsWith("\"")) + { + temp = temp.substring(1); + } + if (temp.endsWith("\"")) + { + temp = temp.substring(0, temp.length() - 1); + } + return filterEncode(temp); + } + + /** + * Escape a value for use in a filter. + * + * @param value the value to escape. + * @return a properly escaped representation of the supplied value. + */ + private static String filterEncode(String value) + { + if (value == null) + { + return null; + } + + // make buffer roomy + StringBuilder encodedValue = new StringBuilder(value.length() * 2); + + int length = value.length(); + + for (int i = 0; i < length; i++) + { + char c = value.charAt(i); + + if (c < FILTER_ESCAPE_TABLE.length) + { + encodedValue.append(FILTER_ESCAPE_TABLE[c]); + } + else + { + // default: add the char + encodedValue.append(c); + } + } + + return encodedValue.toString(); + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusKey.java new file mode 100644 index 0000000000..7e58ddeeab --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusKey.java @@ -0,0 +1,16 @@ +package org.bouncycastle.pqc.jcajce.interfaces; + +import java.security.Key; + +import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec; + +public interface NTRUPlusKey + extends Key +{ + /** + * Return the parameters for this key. + * + * @return a NTRUPlusParameterSpec + */ + NTRUPlusParameterSpec getParameterSpec(); +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusPrivateKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusPrivateKey.java new file mode 100644 index 0000000000..8fe0afd4d8 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusPrivateKey.java @@ -0,0 +1,9 @@ +package org.bouncycastle.pqc.jcajce.interfaces; + +import java.security.PrivateKey; + +public interface NTRUPlusPrivateKey + extends PrivateKey, NTRUPlusKey +{ +} + diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusPublicKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusPublicKey.java new file mode 100644 index 0000000000..bb276f9d97 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/interfaces/NTRUPlusPublicKey.java @@ -0,0 +1,8 @@ +package org.bouncycastle.pqc.jcajce.interfaces; + +import java.security.PublicKey; + +public interface NTRUPlusPublicKey + extends PublicKey, NTRUPlusKey +{ +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java index 3dd7d64e09..0b8662d5bb 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java @@ -41,7 +41,8 @@ public class BouncyCastlePQCProvider "SPHINCS", "LMS", "NH", "XMSS", "SPHINCSPlus", "CMCE", "Frodo", "SABER", "Picnic", "NTRU", "Falcon", "Kyber", "Dilithium", "NTRUPrime", "BIKE", "HQC", "Rainbow", - "Mayo", "Snova" + "Mayo", "Snova", + "NTRUPlus" }; /** diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java index 882e9a2ee2..a82ef8846a 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/HQC.java @@ -4,6 +4,7 @@ import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.jcajce.util.SpiUtil; import org.bouncycastle.pqc.jcajce.provider.hqc.HQCKeyFactorySpi; public class HQC @@ -38,10 +39,7 @@ public void configure(ConfigurableProvider provider) AsymmetricKeyInfoConverter keyFact = new HQCKeyFactorySpi(); - provider.addAlgorithm("Cipher.HQC", PREFIX + "HQCCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher.HQC", "HQC"); - provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_hqc, "HQC"); - + addCipherAlgorithm(provider, "HQC", PREFIX + "HQCCipherSpi$Base", BCObjectIdentifiers.pqc_kem_hqc); addCipherAlgorithm(provider, "HQC128", PREFIX + "HQCCipherSpi$HQC128", BCObjectIdentifiers.hqc128); addCipherAlgorithm(provider, "HQC192", PREFIX + "HQCCipherSpi$HQC192", BCObjectIdentifiers.hqc192); addCipherAlgorithm(provider, "HQC256", PREFIX + "HQCCipherSpi$HQC256", BCObjectIdentifiers.hqc256); @@ -50,7 +48,15 @@ public void configure(ConfigurableProvider provider) provider.addKeyInfoConverter(BCObjectIdentifiers.hqc128, keyFact); provider.addKeyInfoConverter(BCObjectIdentifiers.hqc192, keyFact); provider.addKeyInfoConverter(BCObjectIdentifiers.hqc256, keyFact); + + if (SpiUtil.hasKEM()) + { + provider.addAlgorithm("KEM.HQC", PREFIX + "HQCKEMSpi$HQC"); + + addKEMAlgorithm(provider, "HQC-128", PREFIX + "HQCKEMSpi$HQC128", BCObjectIdentifiers.hqc128); + addKEMAlgorithm(provider, "HQC-192", PREFIX + "HQCKEMSpi$HQC192", BCObjectIdentifiers.hqc192); + addKEMAlgorithm(provider, "HQC-256", PREFIX + "HQCKEMSpi$HQC256", BCObjectIdentifiers.hqc256); + } } } } - diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRU.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRU.java index baf13c51a3..167231d04c 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRU.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRU.java @@ -4,6 +4,7 @@ import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.jcajce.util.SpiUtil; import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi; public class NTRU @@ -27,22 +28,33 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps2048509, "NTRU"); provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps2048677, "NTRU"); provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps4096821, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhps40961229, "NTRU"); provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhrss701, "NTRU"); + provider.addAlgorithm("Alg.Alias.KeyGenerator." + BCObjectIdentifiers.ntruhrss1373, "NTRU"); AsymmetricKeyInfoConverter keyFact = new NTRUKeyFactorySpi(); - provider.addAlgorithm("Cipher.NTRU", PREFIX + "NTRUCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntru, "NTRU"); + addCipherAlgorithm(provider, "NTRU", PREFIX + "NTRUCipherSpi$Base", BCObjectIdentifiers.pqc_kem_ntru); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps2048509, "NTRU"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps2048677, "NTRU"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps4096821, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhps40961229, "NTRU"); provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhrss701, "NTRU"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruhrss1373, "NTRU"); registerOid(provider, BCObjectIdentifiers.pqc_kem_ntru, "NTRU", keyFact); registerOid(provider, BCObjectIdentifiers.ntruhps2048509, "NTRU", keyFact); registerOid(provider, BCObjectIdentifiers.ntruhps2048677, "NTRU", keyFact); registerOid(provider, BCObjectIdentifiers.ntruhps4096821, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhps40961229, "NTRU", keyFact); registerOid(provider, BCObjectIdentifiers.ntruhrss701, "NTRU", keyFact); + registerOid(provider, BCObjectIdentifiers.ntruhrss1373, "NTRU", keyFact); + + if (SpiUtil.hasKEM()) + { + // TODO Per-parameter-set SPI classes? + addKEMAlgorithm(provider, "NTRU", PREFIX + "NTRUKEMSpi$NTRU", BCObjectIdentifiers.pqc_kem_ntru); + } } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPlus.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPlus.java new file mode 100644 index 0000000000..651ac6bc8e --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPlus.java @@ -0,0 +1,55 @@ +package org.bouncycastle.pqc.jcajce.provider; + +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; +import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.pqc.jcajce.provider.ntruplus.NTRUPlusKeyFactorySpi; + +public class NTRUPlus +{ + private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".ntruplus."; + + public static class Mappings + extends AsymmetricAlgorithmProvider + { + public Mappings() + { + } + + public void configure(ConfigurableProvider provider) + { + provider.addAlgorithm("KeyFactory.NTRUPLUS", PREFIX + "NTRUPlusKeyFactorySpi"); + provider.addAlgorithm("Alg.Alias.KeyFactory.NTRUPLUS", "NTRUPLUS"); + addKeyFactoryAlgorithm(provider, "NTRU+KEM-768", PREFIX + "NTRUPlusKeyFactorySpi$NTRUPlus768", BCObjectIdentifiers.ntruPlus768, new NTRUPlusKeyFactorySpi.NTRUPlus768()); + addKeyFactoryAlgorithm(provider, "NTRU+KEM-864", PREFIX + "NTRUPlusKeyFactorySpi$NTRUPlus864", BCObjectIdentifiers.ntruPlus864, new NTRUPlusKeyFactorySpi.NTRUPlus864()); + addKeyFactoryAlgorithm(provider, "NTRU+KEM-1152", PREFIX + "NTRUPlusKeyFactorySpi$NTRUPlus1152", BCObjectIdentifiers.ntruPlus1152, new NTRUPlusKeyFactorySpi.NTRUPlus1152()); + + provider.addAlgorithm("KeyPairGenerator.NTRUPLUS", PREFIX + "NTRUPlusKeyPairGeneratorSpi"); + provider.addAlgorithm("Alg.Alias.KeyPairGenerator.NTRUPLUS", "NTRUPLUS"); + addKeyPairGeneratorAlgorithm(provider, "NTRU+KEM-768", PREFIX + "NTRUPlusKeyPairGeneratorSpi$NTRUPlus768", BCObjectIdentifiers.ntruPlus768); + addKeyPairGeneratorAlgorithm(provider, "NTRU+KEM-864", PREFIX + "NTRUPlusKeyPairGeneratorSpi$NTRUPlus864", BCObjectIdentifiers.ntruPlus864); + addKeyPairGeneratorAlgorithm(provider, "NTRU+KEM-1152", PREFIX + "NTRUPlusKeyPairGeneratorSpi$NTRUPlus1152", BCObjectIdentifiers.ntruPlus1152); + + provider.addAlgorithm("KeyGenerator.NTRUPLUS", PREFIX + "NTRUPlusKeyGeneratorSpi"); + addKeyGeneratorAlgorithm(provider, "NTRU+KEM-768", PREFIX + "NTRUPLUSKeyGeneratorSpi$NTRUPLUS768", BCObjectIdentifiers.ntruPlus768); + addKeyGeneratorAlgorithm(provider, "NTRU+KEM-864", PREFIX + "NTRUPLUSKeyGeneratorSpi$NTRUPLUS864", BCObjectIdentifiers.ntruPlus864); + addKeyGeneratorAlgorithm(provider, "NTRU+KEM-1152", PREFIX + "NTRUPLUSKeyGeneratorSpi$NTRUPLUS1152", BCObjectIdentifiers.ntruPlus1152); + + AsymmetricKeyInfoConverter keyFact = new NTRUPlusKeyFactorySpi(); + + provider.addAlgorithm("Cipher.NTRUPLUS", PREFIX + "NTRUPlusCipherSpi$Base"); + provider.addAlgorithm("Alg.Alias.Cipher.NTRUPLUS", "NTRUPLUS"); + provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.ntruPlus, "NTRUPLUS"); + + addCipherAlgorithm(provider, "NTRU+KEM-768", PREFIX + "NTRUPLUSCipherSpi$NTRUPLUS768", BCObjectIdentifiers.ntruPlus768); + addCipherAlgorithm(provider, "NTRU+KEM-864", PREFIX + "NTRUPLUSCipherSpi$NTRUPLUS864", BCObjectIdentifiers.ntruPlus864); + addCipherAlgorithm(provider, "NTRU+KEM-1152", PREFIX + "NTRUPLUSCipherSpi$NTRUPLUS1152", BCObjectIdentifiers.ntruPlus1152); + + registerOid(provider, BCObjectIdentifiers.ntruPlus, "NTRUPLUS", keyFact); + provider.addKeyInfoConverter(BCObjectIdentifiers.ntruPlus768, keyFact); + provider.addKeyInfoConverter(BCObjectIdentifiers.ntruPlus864, keyFact); + provider.addKeyInfoConverter(BCObjectIdentifiers.ntruPlus1152, keyFact); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java index f4d62eac28..630a59a678 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java @@ -4,6 +4,7 @@ import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; +import org.bouncycastle.jcajce.util.SpiUtil; import org.bouncycastle.pqc.jcajce.provider.ntruprime.NTRULPRimeKeyFactorySpi; import org.bouncycastle.pqc.jcajce.provider.ntruprime.SNTRUPrimeKeyFactorySpi; @@ -27,16 +28,15 @@ public void configure(ConfigurableProvider provider) AsymmetricKeyInfoConverter keyFact = new NTRULPRimeKeyFactorySpi(); - provider.addAlgorithm("Cipher.NTRULPRIME", PREFIX + "NTRULPRimeCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntrulprime, "NTRU"); - + addCipherAlgorithm(provider, "NTRULPRIME", PREFIX + "NTRULPRimeCipherSpi$Base", BCObjectIdentifiers.pqc_kem_ntrulprime); + registerOid(provider, BCObjectIdentifiers.ntrulpr653, "NTRULPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.ntrulpr761, "NTRULPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.ntrulpr857, "NTRULPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.ntrulpr953, "NTRULPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.ntrulpr1013, "NTRULPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.ntrulpr1277, "NTRULPRIME", keyFact); - + provider.addAlgorithm("KeyFactory.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyFactorySpi"); provider.addAlgorithm("KeyPairGenerator.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyPairGeneratorSpi"); @@ -44,8 +44,7 @@ public void configure(ConfigurableProvider provider) keyFact = new SNTRUPrimeKeyFactorySpi(); - provider.addAlgorithm("Cipher.SNTRUPRIME", PREFIX + "SNTRUPrimeCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_sntruprime, "NTRU"); + addCipherAlgorithm(provider, "SNTRUPRIME", PREFIX + "SNTRUPrimeCipherSpi$Base", BCObjectIdentifiers.pqc_kem_sntruprime); registerOid(provider, BCObjectIdentifiers.sntrup653, "SNTRUPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.sntrup761, "SNTRUPRIME", keyFact); @@ -53,6 +52,12 @@ public void configure(ConfigurableProvider provider) registerOid(provider, BCObjectIdentifiers.sntrup953, "SNTRUPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.sntrup1013, "SNTRUPRIME", keyFact); registerOid(provider, BCObjectIdentifiers.sntrup1277, "SNTRUPRIME", keyFact); + + if (SpiUtil.hasKEM()) + { + // TODO Per-parameter-set SPI classes? + addKEMAlgorithm(provider, "SNTRUPRIME", PREFIX + "SNTRUPrimeKEMSpi$SNTRUPrime", BCObjectIdentifiers.pqc_kem_sntruprime); + } } } } diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java index 8e51066d8b..7f6fbaf374 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/hqc/HQCCipherSpi.java @@ -19,7 +19,6 @@ import javax.crypto.spec.SecretKeySpec; import javax.security.auth.DestroyFailedException; -import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.Wrapper; @@ -154,7 +153,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (key instanceof BCHQCPublicKey) { wrapKey = (BCHQCPublicKey)key; - kemGen = new HQCKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + kemGen = new HQCKEMGenerator(random); } else { diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java index 4f4417e026..7f4d432d0e 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/kyber/KyberCipherSpi.java @@ -154,7 +154,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (key instanceof BCKyberPublicKey) { wrapKey = (BCKyberPublicKey)key; - kemGen = new MLKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + kemGen = new MLKEMGenerator(random); } else { diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java index f3ed664c1d..842f84fa89 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUCipherSpi.java @@ -19,7 +19,6 @@ import javax.crypto.spec.SecretKeySpec; import javax.security.auth.DestroyFailedException; -import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.Wrapper; @@ -145,7 +144,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (key instanceof BCNTRUPublicKey) { wrapKey = (BCNTRUPublicKey)key; - kemGen = new NTRUKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + kemGen = new NTRUKEMGenerator(random); } else { diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/BCNTRUPlusPrivateKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/BCNTRUPlusPrivateKey.java new file mode 100644 index 0000000000..4f083325e3 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/BCNTRUPlusPrivateKey.java @@ -0,0 +1,130 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruplus; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.PrivateKey; + +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory; +import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory; +import org.bouncycastle.pqc.jcajce.interfaces.NTRUPlusKey; +import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +public class BCNTRUPlusPrivateKey + implements PrivateKey, NTRUPlusKey +{ + private static final long serialVersionUID = 1L; + + private transient NTRUPlusPrivateKeyParameters params; + private transient ASN1Set attributes; + + public BCNTRUPlusPrivateKey( + NTRUPlusPrivateKeyParameters params) + { + this.params = params; + } + + public BCNTRUPlusPrivateKey(PrivateKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(PrivateKeyInfo keyInfo) + throws IOException + { + this.attributes = keyInfo.getAttributes(); + this.params = (NTRUPlusPrivateKeyParameters) PrivateKeyFactory.createKey(keyInfo); + } + + /** + * Compare this private key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCNTRUPlusPrivateKey) + { + BCNTRUPlusPrivateKey otherKey = (BCNTRUPlusPrivateKey)o; + + return Arrays.areEqual(params.getEncoded(), otherKey.params.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(params.getEncoded()); + } + + /** + * @return name of the algorithm - "NTRUPlus" + */ + public final String getAlgorithm() + { + return Strings.toUpperCase(params.getParameters().getName()); + } + + public byte[] getEncoded() + { + + try + { + PrivateKeyInfo pki = PrivateKeyInfoFactory.createPrivateKeyInfo(params, attributes); + + return pki.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + public NTRUPlusParameterSpec getParameterSpec() + { + return NTRUPlusParameterSpec.fromName(params.getParameters().getName()); + } + + public String getFormat() + { + return "PKCS#8"; + } + + NTRUPlusPrivateKeyParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(PrivateKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/BCNTRUPlusPublicKey.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/BCNTRUPlusPublicKey.java new file mode 100644 index 0000000000..c5a5e3d295 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/BCNTRUPlusPublicKey.java @@ -0,0 +1,126 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruplus; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.PublicKey; + +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPublicKeyParameters; +import org.bouncycastle.pqc.crypto.util.PublicKeyFactory; +import org.bouncycastle.pqc.crypto.util.SubjectPublicKeyInfoFactory; +import org.bouncycastle.pqc.jcajce.interfaces.NTRUPlusKey; +import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +public class BCNTRUPlusPublicKey + implements PublicKey, NTRUPlusKey +{ + private static final long serialVersionUID = 1L; + + private transient NTRUPlusPublicKeyParameters params; + + public BCNTRUPlusPublicKey( + NTRUPlusPublicKeyParameters params) + { + this.params = params; + } + + public BCNTRUPlusPublicKey(SubjectPublicKeyInfo keyInfo) + throws IOException + { + init(keyInfo); + } + + private void init(SubjectPublicKeyInfo keyInfo) + throws IOException + { + this.params = (NTRUPlusPublicKeyParameters) PublicKeyFactory.createKey(keyInfo); + } + + /** + * Compare this NTRUPlus public key with another object. + * + * @param o the other object + * @return the result of the comparison + */ + public boolean equals(Object o) + { + if (o == this) + { + return true; + } + + if (o instanceof BCNTRUPlusPublicKey) + { + BCNTRUPlusPublicKey otherKey = (BCNTRUPlusPublicKey)o; + + return Arrays.areEqual(params.getEncoded(), otherKey.params.getEncoded()); + } + + return false; + } + + public int hashCode() + { + return Arrays.hashCode(params.getEncoded()); + } + + /** + * @return name of the algorithm - "NTRUPlus" + */ + public final String getAlgorithm() + { + return Strings.toUpperCase(params.getParameters().getName()); + } + + public byte[] getEncoded() + { + try + { + SubjectPublicKeyInfo pki = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(params); + + return pki.getEncoded(); + } + catch (IOException e) + { + return null; + } + } + + public String getFormat() + { + return "X.509"; + } + + public NTRUPlusParameterSpec getParameterSpec() + { + return NTRUPlusParameterSpec.fromName(params.getParameters().getName()); + } + + NTRUPlusPublicKeyParameters getKeyParams() + { + return params; + } + + private void readObject( + ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + byte[] enc = (byte[])in.readObject(); + + init(SubjectPublicKeyInfo.getInstance(enc)); + } + + private void writeObject( + ObjectOutputStream out) + throws IOException + { + out.defaultWriteObject(); + + out.writeObject(this.getEncoded()); + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusCipherSpi.java new file mode 100644 index 0000000000..7efc31e7c5 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusCipherSpi.java @@ -0,0 +1,359 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruplus; + +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.CipherSpi; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.SecretKeySpec; +import javax.security.auth.DestroyFailedException; + +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.crypto.Wrapper; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKEMExtractor; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKEMGenerator; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; +import org.bouncycastle.pqc.jcajce.provider.util.WrapUtil; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Exceptions; +import org.bouncycastle.util.Strings; + +class NTRUPlusCipherSpi + extends CipherSpi +{ + private final String algorithmName; + private NTRUPlusKEMGenerator kemGen; + private KTSParameterSpec kemParameterSpec; + private BCNTRUPlusPublicKey wrapKey; + private BCNTRUPlusPrivateKey unwrapKey; + private AlgorithmParameters engineParams; + private NTRUPlusParameters ntruplusParameters; + + NTRUPlusCipherSpi(String algorithmName) + throws NoSuchAlgorithmException + { + this.algorithmName = algorithmName; + } + + NTRUPlusCipherSpi(NTRUPlusParameters ntruplusParameters) + { + this.ntruplusParameters = ntruplusParameters; + this.algorithmName = Strings.toUpperCase(ntruplusParameters.getName()); + } + + @Override + protected void engineSetMode(String mode) + throws NoSuchAlgorithmException + { + throw new NoSuchAlgorithmException("Cannot support mode " + mode); + } + + @Override + protected void engineSetPadding(String padding) + throws NoSuchPaddingException + { + throw new NoSuchPaddingException("Padding " + padding + " unknown"); + } + + protected int engineGetKeySize( + Key key) + { + return 2048; // TODO + //throw new IllegalArgumentException("not an valid key!"); + } + + @Override + protected int engineGetBlockSize() + { + return 0; + } + + @Override + protected int engineGetOutputSize(int i) + { + return -1; // can't use with update/doFinal + } + + @Override + protected byte[] engineGetIV() + { + return null; + } + + @Override + protected AlgorithmParameters engineGetParameters() + { + if (engineParams == null) + { + try + { + engineParams = AlgorithmParameters.getInstance(algorithmName, "BCPQC"); + + engineParams.init(kemParameterSpec); + } + catch (Exception e) + { + throw Exceptions.illegalStateException(e.toString(), e); + } + } + + return engineParams; + } + + @Override + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException + { + try + { + engineInit(opmode, key, (AlgorithmParameterSpec)null, random); + } + catch (InvalidAlgorithmParameterException e) + { + throw Exceptions.illegalArgumentException(e.getMessage(), e); + } + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + if (paramSpec == null) + { + // TODO: default should probably use shake. + kemParameterSpec = new KEMParameterSpec("AES-KWP"); + } + else + { + if (!(paramSpec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException(algorithmName + " can only accept KTSParameterSpec"); + } + + kemParameterSpec = (KTSParameterSpec)paramSpec; + } + + if (opmode == Cipher.WRAP_MODE) + { + if (key instanceof BCNTRUPlusPublicKey) + { + wrapKey = (BCNTRUPlusPublicKey)key; + kemGen = new NTRUPlusKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + } + else + { + throw new InvalidKeyException("Only a " + algorithmName + " public key can be used for wrapping"); + } + } + else if (opmode == Cipher.UNWRAP_MODE) + { + if (key instanceof BCNTRUPlusPrivateKey) + { + unwrapKey = (BCNTRUPlusPrivateKey)key; + } + else + { + throw new InvalidKeyException("Only a " + algorithmName + " private key can be used for unwrapping"); + } + } + else + { + throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping"); + } + + if (ntruplusParameters != null) + { + String canonicalAlgName = Strings.toUpperCase(ntruplusParameters.getName()); + if (!canonicalAlgName.equals(key.getAlgorithm())) + { + throw new InvalidKeyException("cipher locked to " + canonicalAlgName); + } + } + } + + @Override + protected void engineInit(int opmode, Key key, AlgorithmParameters algorithmParameters, SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + AlgorithmParameterSpec paramSpec = null; + + if (algorithmParameters != null) + { + try + { + paramSpec = algorithmParameters.getParameterSpec(KEMParameterSpec.class); + } + catch (Exception e) + { + throw new InvalidAlgorithmParameterException("can't handle parameter " + algorithmParameters.toString()); + } + } + + engineInit(opmode, key, paramSpec, random); + } + + @Override + protected byte[] engineUpdate(byte[] bytes, int i, int i1) + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + @Override + protected int engineUpdate(byte[] bytes, int i, int i1, byte[] bytes1, int i2) + throws ShortBufferException + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + @Override + protected byte[] engineDoFinal(byte[] bytes, int i, int i1) + throws IllegalBlockSizeException, BadPaddingException + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + @Override + protected int engineDoFinal(byte[] bytes, int i, int i1, byte[] bytes1, int i2) + throws ShortBufferException, IllegalBlockSizeException, BadPaddingException + { + throw new IllegalStateException("Not supported in a wrapping mode"); + } + + protected byte[] engineWrap( + Key key) + throws IllegalBlockSizeException, InvalidKeyException + { + byte[] encoded = key.getEncoded(); + if (encoded == null) + { + throw new InvalidKeyException("Cannot wrap key, null encoding."); + } + + try + { + SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(wrapKey.getKeyParams()); + + Wrapper kWrap = WrapUtil.getWrapper(kemParameterSpec.getKeyAlgorithmName()); + + KeyParameter keyParameter = new KeyParameter(WrapUtil.trimSecret(kemParameterSpec.getKeyAlgorithmName(), secEnc.getSecret())); + + kWrap.init(true, keyParameter); + + byte[] encapsulation = secEnc.getEncapsulation(); + + secEnc.destroy(); + + byte[] keyToWrap = key.getEncoded(); + + byte[] rv = Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); + + Arrays.clear(keyToWrap); + + return rv; + } + catch (IllegalArgumentException e) + { + throw new IllegalBlockSizeException("unable to generate KTS secret: " + e.getMessage()); + } + catch (DestroyFailedException e) + { + throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + } + } + + protected Key engineUnwrap( + byte[] wrappedKey, + String wrappedKeyAlgorithm, + int wrappedKeyType) + throws InvalidKeyException, NoSuchAlgorithmException + { + // TODO: add support for other types. + if (wrappedKeyType != Cipher.SECRET_KEY) + { + throw new InvalidKeyException("only SECRET_KEY supported"); + } + try + { + NTRUPlusKEMExtractor kemExt = new NTRUPlusKEMExtractor(unwrapKey.getKeyParams()); + + byte[] secret = kemExt.extractSecret(Arrays.copyOfRange(wrappedKey, 0, kemExt.getEncapsulationLength())); + + Wrapper kWrap = WrapUtil.getWrapper(kemParameterSpec.getKeyAlgorithmName()); + + KeyParameter keyParameter = new KeyParameter(WrapUtil.trimSecret(kemParameterSpec.getKeyAlgorithmName(), secret)); + + Arrays.clear(secret); + + kWrap.init(false, keyParameter); + + byte[] keyEncBytes = Arrays.copyOfRange(wrappedKey, kemExt.getEncapsulationLength(), wrappedKey.length); + + SecretKey rv = new SecretKeySpec(kWrap.unwrap(keyEncBytes, 0, keyEncBytes.length), wrappedKeyAlgorithm); + + Arrays.clear(keyParameter.getKey()); + + return rv; + } + catch (IllegalArgumentException e) + { + throw new NoSuchAlgorithmException("unable to extract KTS secret: " + e.getMessage()); + } + catch (InvalidCipherTextException e) + { + throw new InvalidKeyException("unable to extract KTS secret: " + e.getMessage()); + } + } + + public static class Base + extends NTRUPlusCipherSpi + { + public Base() + throws NoSuchAlgorithmException + { + super("NTRU+"); + } + } + + public static class NTRUPlus768 + extends NTRUPlusCipherSpi + { + public NTRUPlus768() + { + super(NTRUPlusParameters.ntruplus_kem_864); + } + } + + public static class NTRUPlus864 + extends NTRUPlusCipherSpi + { + public NTRUPlus864() + { + super(NTRUPlusParameters.ntruplus_kem_864); + } + } + + public static class NTRUPlus1152 + extends NTRUPlusCipherSpi + { + public NTRUPlus1152() + { + super(NTRUPlusParameters.ntruplus_kem_1152); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyFactorySpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyFactorySpi.java new file mode 100644 index 0000000000..4532f5c9e7 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyFactorySpi.java @@ -0,0 +1,164 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruplus; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashSet; +import java.util.Set; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.pqc.jcajce.provider.util.BaseKeyFactorySpi; + +public class NTRUPlusKeyFactorySpi + extends BaseKeyFactorySpi +{ + private static final Set keyOids = new HashSet(); + + static + { + keyOids.add(BCObjectIdentifiers.ntruPlus768); + keyOids.add(BCObjectIdentifiers.ntruPlus864); + keyOids.add(BCObjectIdentifiers.ntruPlus1152); + } + + public NTRUPlusKeyFactorySpi() + { + super(keyOids); + } + + public NTRUPlusKeyFactorySpi(ASN1ObjectIdentifier keyOids) + { + super(keyOids); + } + + public PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof PKCS8EncodedKeySpec) + { + // get the DER-encoded Key according to PKCS#8 from the spec + byte[] encKey = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); + + try + { + return generatePrivate(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(encKey))); + } + catch (Exception e) + { + throw new InvalidKeySpecException(e.toString()); + } + } + + throw new InvalidKeySpecException("Unsupported key specification: " + + keySpec.getClass() + "."); + } + + public PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof X509EncodedKeySpec) + { + // get the DER-encoded Key according to X.509 from the spec + byte[] encKey = ((X509EncodedKeySpec)keySpec).getEncoded(); + + // decode the SubjectPublicKeyInfo data structure to the pki object + try + { + return generatePublic(SubjectPublicKeyInfo.getInstance(encKey)); + } + catch (Exception e) + { + throw new InvalidKeySpecException(e.toString()); + } + } + + throw new InvalidKeySpecException("Unknown key specification: " + keySpec + "."); + } + + public final KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof BCNTRUPlusPrivateKey) + { + if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new PKCS8EncodedKeySpec(key.getEncoded()); + } + } + else if (key instanceof BCNTRUPlusPublicKey) + { + if (X509EncodedKeySpec.class.isAssignableFrom(keySpec)) + { + return new X509EncodedKeySpec(key.getEncoded()); + } + } + else + { + throw new InvalidKeySpecException("Unsupported key type: " + + key.getClass() + "."); + } + + throw new InvalidKeySpecException("Unknown key specification: " + + keySpec + "."); + } + + public final Key engineTranslateKey(Key key) + throws InvalidKeyException + { + if (key instanceof BCNTRUPlusPrivateKey || key instanceof BCNTRUPlusPublicKey) + { + return key; + } + + throw new InvalidKeyException("Unsupported key type"); + } + + public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) + throws IOException + { + return new BCNTRUPlusPrivateKey(keyInfo); + } + + public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) + throws IOException + { + return new BCNTRUPlusPublicKey(keyInfo); + } + + public static class NTRUPlus768 + extends NTRUPlusKeyFactorySpi + { + public NTRUPlus768() + { + super(BCObjectIdentifiers.ntruPlus768); + } + } + + public static class NTRUPlus864 + extends NTRUPlusKeyFactorySpi + { + public NTRUPlus864() + { + super(BCObjectIdentifiers.ntruPlus864); + } + } + + public static class NTRUPlus1152 + extends NTRUPlusKeyFactorySpi + { + public NTRUPlus1152() + { + super(BCObjectIdentifiers.ntruPlus1152); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyGeneratorSpi.java new file mode 100644 index 0000000000..6a87689f71 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyGeneratorSpi.java @@ -0,0 +1,150 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruplus; + +import java.security.InvalidAlgorithmParameterException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import javax.security.auth.DestroyFailedException; + +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; +import org.bouncycastle.jcajce.spec.KEMExtractSpec; +import org.bouncycastle.jcajce.spec.KEMGenerateSpec; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKEMExtractor; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKEMGenerator; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; +import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec; +import org.bouncycastle.util.Arrays; + +public class NTRUPlusKeyGeneratorSpi + extends KeyGeneratorSpi +{ + private KEMGenerateSpec genSpec; + private SecureRandom random; + private KEMExtractSpec extSpec; + private NTRUPlusParameters ntruplusParameters; + + public NTRUPlusKeyGeneratorSpi() + { + this(null); + } + + public NTRUPlusKeyGeneratorSpi(NTRUPlusParameters ntruplusParameters) + { + this.ntruplusParameters = ntruplusParameters; + } + + protected void engineInit(SecureRandom secureRandom) + { + throw new UnsupportedOperationException("Operation not supported"); + } + + protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec, SecureRandom secureRandom) + throws InvalidAlgorithmParameterException + { + this.random = secureRandom; + if (algorithmParameterSpec instanceof KEMGenerateSpec) + { + this.genSpec = (KEMGenerateSpec)algorithmParameterSpec; + this.extSpec = null; + if (ntruplusParameters != null) + { + String canonicalAlgName = NTRUPlusParameterSpec.fromName(ntruplusParameters.getName()).getName(); + if (!canonicalAlgName.equals(genSpec.getPublicKey().getAlgorithm())) + { + throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); + } + } + } + else if (algorithmParameterSpec instanceof KEMExtractSpec) + { + this.genSpec = null; + this.extSpec = (KEMExtractSpec)algorithmParameterSpec; + if (ntruplusParameters != null) + { + String canonicalAlgName = NTRUPlusParameterSpec.fromName(ntruplusParameters.getName()).getName(); + if (!canonicalAlgName.equals(extSpec.getPrivateKey().getAlgorithm())) + { + throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); + } + } + } + else + { + throw new InvalidAlgorithmParameterException("unknown spec"); + } + } + + protected void engineInit(int i, SecureRandom secureRandom) + { + throw new UnsupportedOperationException("Operation not supported"); + } + + protected SecretKey engineGenerateKey() + { + if (genSpec != null) + { + BCNTRUPlusPublicKey pubKey = (BCNTRUPlusPublicKey)genSpec.getPublicKey(); + NTRUPlusKEMGenerator kemGen = new NTRUPlusKEMGenerator(random); + + SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(pubKey.getKeyParams()); + + SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secEnc.getSecret(), genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); + + try + { + secEnc.destroy(); + } + catch (DestroyFailedException e) + { + throw new IllegalStateException("key cleanup failed"); + } + + return rv; + } + else + { + BCNTRUPlusPrivateKey privKey = (BCNTRUPlusPrivateKey)extSpec.getPrivateKey(); + NTRUPlusKEMExtractor kemExt = new NTRUPlusKEMExtractor(privKey.getKeyParams()); + + byte[] encapsulation = extSpec.getEncapsulation(); + byte[] secret = kemExt.extractSecret(encapsulation); + + SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, extSpec.getKeyAlgorithmName()), encapsulation); + + Arrays.clear(secret); + + return rv; + } + } + + public static class NTRUPlus768 + extends NTRUPlusKeyGeneratorSpi + { + public NTRUPlus768() + { + super(NTRUPlusParameters.ntruplus_kem_768); + } + } + + public static class NTRUPlus864 + extends NTRUPlusKeyGeneratorSpi + { + public NTRUPlus864() + { + super(NTRUPlusParameters.ntruplus_kem_864); + } + } + + public static class NTRUPlus1152 + extends NTRUPlusKeyGeneratorSpi + { + public NTRUPlus1152() + { + super(NTRUPlusParameters.ntruplus_kem_1152); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyPairGeneratorSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyPairGeneratorSpi.java new file mode 100644 index 0000000000..55f5262863 --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruplus/NTRUPlusKeyPairGeneratorSpi.java @@ -0,0 +1,150 @@ +package org.bouncycastle.pqc.jcajce.provider.ntruplus; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.jcajce.util.SpecUtil; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKeyGenerationParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusKeyPairGenerator; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPrivateKeyParameters; +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusPublicKeyParameters; +import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec; +import org.bouncycastle.util.Strings; + +public class NTRUPlusKeyPairGeneratorSpi + extends java.security.KeyPairGenerator +{ + private static Map parameters = new HashMap(); + + static + { + parameters.put(NTRUPlusParameterSpec.ntruplus_768.getName(), NTRUPlusParameters.ntruplus_kem_768); + parameters.put(NTRUPlusParameterSpec.ntruplus_864.getName(), NTRUPlusParameters.ntruplus_kem_864); + parameters.put(NTRUPlusParameterSpec.ntruplus_1152.getName(), NTRUPlusParameters.ntruplus_kem_1152); + } + + private final NTRUPlusParameters ntruplusParameters; + + NTRUPlusKeyGenerationParameters param; + NTRUPlusKeyPairGenerator engine = new NTRUPlusKeyPairGenerator(); + + SecureRandom random = CryptoServicesRegistrar.getSecureRandom(); + boolean initialised = false; + + public NTRUPlusKeyPairGeneratorSpi() + { + super("NTRUPLUS"); + this.ntruplusParameters = null; + } + + protected NTRUPlusKeyPairGeneratorSpi(NTRUPlusParameters ntruplusParameters) + { + super(ntruplusParameters.getName()); + this.ntruplusParameters = ntruplusParameters; + } + + public void initialize( + int strength, + SecureRandom random) + { + throw new IllegalArgumentException("use AlgorithmParameterSpec"); + } + + public void initialize( + AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException + { + String name = getNameFromParams(params); + + if (name != null && parameters.containsKey(name)) + { + NTRUPlusParameters ntruplusParams = (NTRUPlusParameters)parameters.get(name); + + param = new NTRUPlusKeyGenerationParameters(random, ntruplusParams); + + if (ntruplusParameters != null && !ntruplusParams.getName().equals(ntruplusParameters.getName())) + { + throw new InvalidAlgorithmParameterException("key pair generator locked to " + Strings.toUpperCase(ntruplusParameters.getName())); + } + + engine.init(param); + initialised = true; + } + else + { + throw new InvalidAlgorithmParameterException("invalid ParameterSpec: " + params); + } + } + + private static String getNameFromParams(AlgorithmParameterSpec paramSpec) + { + if (paramSpec instanceof NTRUPlusParameterSpec) + { + NTRUPlusParameterSpec ntruplusParams = (NTRUPlusParameterSpec)paramSpec; + return ntruplusParams.getName(); + } + else + { + return Strings.toLowerCase(SpecUtil.getNameFrom(paramSpec)); + } + } + + public KeyPair generateKeyPair() + { + if (!initialised) + { + if (ntruplusParameters != null) + { + param = new NTRUPlusKeyGenerationParameters(random, ntruplusParameters); + } + else + { + param = new NTRUPlusKeyGenerationParameters(random, NTRUPlusParameters.ntruplus_kem_768); + } + + engine.init(param); + initialised = true; + } + + AsymmetricCipherKeyPair pair = engine.generateKeyPair(); + NTRUPlusPublicKeyParameters pub = (NTRUPlusPublicKeyParameters)pair.getPublic(); + NTRUPlusPrivateKeyParameters priv = (NTRUPlusPrivateKeyParameters)pair.getPrivate(); + + return new KeyPair(new BCNTRUPlusPublicKey(pub), new BCNTRUPlusPrivateKey(priv)); + } + + public static class NTRUPlus768 + extends NTRUPlusKeyPairGeneratorSpi + { + public NTRUPlus768() + { + super(NTRUPlusParameters.ntruplus_kem_768); + } + } + + public static class NTRUPlus864 + extends NTRUPlusKeyPairGeneratorSpi + { + public NTRUPlus864() + { + super(NTRUPlusParameters.ntruplus_kem_864); + } + } + + public static class NTRUPlus1152 + extends NTRUPlusKeyPairGeneratorSpi + { + public NTRUPlus1152() + { + super(NTRUPlusParameters.ntruplus_kem_864); + } + } +} diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java index af92dfd3a6..9c1da960a7 100644 --- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeCipherSpi.java @@ -19,7 +19,6 @@ import javax.crypto.spec.SecretKeySpec; import javax.security.auth.DestroyFailedException; -import org.bouncycastle.crypto.CryptoServicesRegistrar; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.crypto.Wrapper; @@ -144,7 +143,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec paramSpec, if (key instanceof BCSNTRUPrimePublicKey) { wrapKey = (BCSNTRUPrimePublicKey)key; - kemGen = new SNTRUPrimeKEMGenerator(CryptoServicesRegistrar.getSecureRandom(random)); + kemGen = new SNTRUPrimeKEMGenerator(random); } else { diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/NTRUPlusParameterSpec.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/NTRUPlusParameterSpec.java new file mode 100644 index 0000000000..cb8c8e23ad --- /dev/null +++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/spec/NTRUPlusParameterSpec.java @@ -0,0 +1,42 @@ +package org.bouncycastle.pqc.jcajce.spec; + +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.Map; + +import org.bouncycastle.pqc.crypto.ntruplus.NTRUPlusParameters; +import org.bouncycastle.util.Strings; + +public class NTRUPlusParameterSpec + implements AlgorithmParameterSpec +{ + public static final NTRUPlusParameterSpec ntruplus_768 = new NTRUPlusParameterSpec(NTRUPlusParameters.ntruplus_kem_768); + public static final NTRUPlusParameterSpec ntruplus_864 = new NTRUPlusParameterSpec(NTRUPlusParameters.ntruplus_kem_864); + public static final NTRUPlusParameterSpec ntruplus_1152 = new NTRUPlusParameterSpec(NTRUPlusParameters.ntruplus_kem_1152); + + private static Map parameters = new HashMap(); + + static + { + parameters.put("ntruplus-768", ntruplus_768); + parameters.put("ntruplus-864", ntruplus_864); + parameters.put("ntruplus-864", ntruplus_864); + } + + private final String name; + + private NTRUPlusParameterSpec(NTRUPlusParameters parameters) + { + this.name = Strings.toUpperCase(parameters.getName()); + } + + public String getName() + { + return name; + } + + public static NTRUPlusParameterSpec fromName(String name) + { + return (NTRUPlusParameterSpec)parameters.get(Strings.toLowerCase(name)); + } +} \ No newline at end of file diff --git a/prov/src/main/java/org/bouncycastle/x509/X509Util.java b/prov/src/main/java/org/bouncycastle/x509/X509Util.java index 027b0133e4..dc8d44303a 100644 --- a/prov/src/main/java/org/bouncycastle/x509/X509Util.java +++ b/prov/src/main/java/org/bouncycastle/x509/X509Util.java @@ -133,7 +133,7 @@ private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), - new ASN1Integer(saltSize), + ASN1Integer.valueOf(saltSize), RSASSAPSSparams.DEFAULT_TRAILER_FIELD); } diff --git a/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java b/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java index 8121a498ed..e1af28594a 100644 --- a/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java +++ b/prov/src/main/java/org/bouncycastle/x509/util/LDAPStoreHelper.java @@ -35,6 +35,7 @@ import org.bouncycastle.jce.provider.X509CRLParser; import org.bouncycastle.jce.provider.X509CertPairParser; import org.bouncycastle.jce.provider.X509CertParser; +import org.bouncycastle.ldap.LDAPUtils; import org.bouncycastle.util.StoreException; import org.bouncycastle.util.Strings; import org.bouncycastle.x509.X509AttributeCertStoreSelector; @@ -65,7 +66,6 @@ */ public class LDAPStoreHelper { - // TODO: cache results private X509LDAPCertStoreParameters params; @@ -95,7 +95,8 @@ public LDAPStoreHelper(X509LDAPCertStoreParameters params) */ private static final String URL_CONTEXT_PREFIX = "com.sun.jndi.url"; - private DirContext connectLDAP() throws NamingException + private DirContext connectLDAP() + throws NamingException { Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LDAP_PROVIDER); @@ -111,47 +112,6 @@ private DirContext connectLDAP() throws NamingException return ctx; } - private String parseDN(String subject, String dNAttributeName) - { - String temp = subject; - int begin = Strings.toLowerCase(temp).indexOf( - Strings.toLowerCase(dNAttributeName) + "="); - if (begin == -1) - { - return ""; - } - temp = temp.substring(begin + dNAttributeName.length()); - int end = temp.indexOf(','); - if (end == -1) - { - end = temp.length(); - } - while (temp.charAt(end - 1) == '\\') - { - end = temp.indexOf(',', end + 1); - if (end == -1) - { - end = temp.length(); - } - } - temp = temp.substring(0, end); - begin = temp.indexOf('='); - temp = temp.substring(begin + 1); - if (temp.charAt(0) == ' ') - { - temp = temp.substring(1); - } - if (temp.startsWith("\"")) - { - temp = temp.substring(1); - } - if (temp.endsWith("\"")) - { - temp = temp.substring(0, temp.length() - 1); - } - return temp; - } - private Set createCerts(List list, X509CertStoreSelector xselector) throws StoreException { @@ -224,7 +184,7 @@ private List certSubjectSerialSearch(X509CertStoreSelector xselector, { for (int i = 0; i < subjectAttributeNames.length; i++) { - attrValue = parseDN(subject, subjectAttributeNames[i]); + attrValue = LDAPUtils.parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); @@ -235,7 +195,7 @@ private List certSubjectSerialSearch(X509CertStoreSelector xselector, attrValue = serial; list.addAll(search( splitString(params.getSearchForSerialNumberIn()), - attrValue, attrs)); + attrValue, attrs)); } if (serial == null && subject == null) { @@ -246,7 +206,6 @@ private List certSubjectSerialSearch(X509CertStoreSelector xselector, } - /** * Can use the subject of the forward certificate of the set certificate * pair or the subject of the forward @@ -290,7 +249,7 @@ private List crossCertificatePairSubjectSearch( { for (int i = 0; i < subjectAttributeNames.length; i++) { - attrValue = parseDN(subject, subjectAttributeNames[i]); + attrValue = LDAPUtils.parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); @@ -385,7 +344,7 @@ private List attrCertSubjectSerialSearch( { for (int i = 0; i < subjectAttributeNames.length; i++) { - attrValue = parseDN(subject, subjectAttributeNames[i]); + attrValue = LDAPUtils.parseDN(subject, subjectAttributeNames[i]); list .addAll(search(attrNames, "*" + attrValue + "*", attrs)); @@ -441,11 +400,11 @@ private List cRLIssuerSearch(X509CRLStoreSelector xselector, if (xselector.getAttrCertificateChecking() != null) { Principal principals[] = xselector.getAttrCertificateChecking().getIssuer().getPrincipals(); - for (int i=0; i + * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs. * @throws StoreException */ public Collection getAttributeCertificateRevocationLists( - X509CRLStoreSelector selector) throws StoreException + X509CRLStoreSelector selector) + throws StoreException { String[] attrs = splitString(params .getAttributeCertificateRevocationListAttribute()); @@ -754,12 +718,14 @@ public Collection getAttributeCertificateRevocationLists( * The attributeAuthorityList holds a list of AA certificates that have been * revoked. *

    + * * @param selector The CRL selector to use to find the CRLs. * @return A possible empty collection with CRLs * @throws StoreException */ public Collection getAttributeAuthorityRevocationLists( - X509CRLStoreSelector selector) throws StoreException + X509CRLStoreSelector selector) + throws StoreException { String[] attrs = splitString(params.getAttributeAuthorityRevocationListAttribute()); String attrNames[] = splitString(params @@ -789,7 +755,8 @@ public Collection getAttributeAuthorityRevocationLists( * @throws StoreException */ public Collection getCrossCertificatePairs( - X509CertPairStoreSelector selector) throws StoreException + X509CertPairStoreSelector selector) + throws StoreException { String[] attrs = splitString(params.getCrossCertificateAttribute()); String attrNames[] = splitString(params.getLdapCrossCertificateAttributeName()); @@ -850,6 +817,7 @@ public Collection getUserCertificates(X509CertStoreSelector selector) *

    * The aAcertificate holds the privileges of an attribute authority. *

    + * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException @@ -882,12 +850,14 @@ public Collection getAACertificates(X509AttributeCertStoreSelector selector) * authority and holds a description of the privilege and its delegation * rules. *

    + * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAttributeDescriptorCertificates( - X509AttributeCertStoreSelector selector) throws StoreException + X509AttributeCertStoreSelector selector) + throws StoreException { String[] attrs = splitString(params.getAttributeDescriptorCertificateAttribute()); String attrNames[] = splitString(params @@ -916,6 +886,7 @@ public Collection getAttributeDescriptorCertificates( * store self-issued certificates (if any) and certificates issued to this * CA by CAs in the same realm as this CA. *

    + * * @param selector The selector to find the certificates. * @return A possible empty collection with certificates. * @throws StoreException @@ -948,7 +919,8 @@ public Collection getCACertificates(X509CertStoreSelector selector) * @throws StoreException */ public Collection getDeltaCertificateRevocationLists( - X509CRLStoreSelector selector) throws StoreException + X509CRLStoreSelector selector) + throws StoreException { String[] attrs = splitString(params.getDeltaRevocationListAttribute()); String attrNames[] = splitString(params.getLdapDeltaRevocationListAttributeName()); @@ -973,12 +945,14 @@ public Collection getDeltaCertificateRevocationLists( *

    * The attributeCertificateAttribute holds the privileges of a user *

    + * * @param selector The selector to find the attribute certificates. * @return A possible empty collection with attribute certificates. * @throws StoreException */ public Collection getAttributeCertificateAttributes( - X509AttributeCertStoreSelector selector) throws StoreException + X509AttributeCertStoreSelector selector) + throws StoreException { String[] attrs = splitString(params.getAttributeCertificateAttributeAttribute()); String attrNames[] = splitString(params @@ -1007,7 +981,8 @@ public Collection getAttributeCertificateAttributes( * @throws StoreException */ public Collection getCertificateRevocationLists( - X509CRLStoreSelector selector) throws StoreException + X509CRLStoreSelector selector) + throws StoreException { String[] attrs = splitString(params.getCertificateRevocationListAttribute()); String attrNames[] = splitString(params diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java index 8731c92a51..882e77b45d 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMCipherSpi.java @@ -32,46 +32,46 @@ import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Exceptions; -class MLKEMCipherSpi +public class MLKEMCipherSpi extends CipherSpi { + private final MLKEMParameters mlkemParameters; private final String algorithmName; + private MLKEMGenerator kemGen; private KTSParameterSpec kemParameterSpec; private BCMLKEMPublicKey wrapKey; private BCMLKEMPrivateKey unwrapKey; private AlgorithmParameters engineParams; - private MLKEMParameters mlkemParamters; - MLKEMCipherSpi(String algorithmName) + public MLKEMCipherSpi(String algorithmName) { + this.mlkemParameters = null; this.algorithmName = algorithmName; - this.mlkemParamters = null; } - MLKEMCipherSpi(MLKEMParameters kyberParameters) + public MLKEMCipherSpi(MLKEMParameters mlkemParameters) { - this.mlkemParamters = kyberParameters; - this.algorithmName = kyberParameters.getName(); + this.mlkemParameters = mlkemParameters; + this.algorithmName = mlkemParameters.getName(); } @Override protected void engineSetMode(String mode) - throws NoSuchAlgorithmException + throws NoSuchAlgorithmException { throw new NoSuchAlgorithmException("Cannot support mode " + mode); } @Override protected void engineSetPadding(String padding) - throws NoSuchPaddingException + throws NoSuchPaddingException { throw new NoSuchPaddingException("Padding " + padding + " unknown"); } - protected int engineGetKeySize( - Key key) + protected int engineGetKeySize(Key key) { return 2048; // TODO //throw new IllegalArgumentException("not an valid key!"); @@ -176,9 +176,9 @@ else if (opmode == Cipher.UNWRAP_MODE) throw new InvalidParameterException("Cipher only valid for wrapping/unwrapping"); } - if (mlkemParamters != null) + if (mlkemParameters != null) { - String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParamters.getName()).getName(); + String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName(); if (!canonicalAlgName.equals(key.getAlgorithm())) { throw new InvalidKeyException("cipher locked to " + canonicalAlgName); @@ -255,11 +255,14 @@ protected byte[] engineWrap( byte[] keyToWrap = key.getEncoded(); - byte[] rv = Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); - - Arrays.clear(keyToWrap); - - return rv; + try + { + return Arrays.concatenate(encapsulation, kWrap.wrap(keyToWrap, 0, keyToWrap.length)); + } + finally + { + Arrays.clear(keyToWrap); + } } catch (IllegalArgumentException e) { @@ -276,7 +279,7 @@ protected byte[] engineWrap( } catch (Exception e) { - throw new IllegalBlockSizeException("unable to destroy interim values: " + e.getMessage()); + // ignore } } } @@ -292,6 +295,7 @@ protected Key engineUnwrap( { throw new InvalidKeyException("only SECRET_KEY supported"); } + byte[] secret = null; try { @@ -317,18 +321,14 @@ protected Key engineUnwrap( } finally { - if (secret != null) - { - Arrays.clear(secret); - } + Arrays.clear(secret); } } public static class Base - extends MLKEMCipherSpi + extends MLKEMCipherSpi { public Base() - throws NoSuchAlgorithmException { super("MLKEM"); } diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java index 6b09d0f4f0..c7da53cf6c 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMKeyGeneratorSpi.java @@ -7,6 +7,7 @@ import javax.crypto.KeyGeneratorSpi; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; +import javax.security.auth.DestroyFailedException; import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; @@ -20,21 +21,22 @@ import org.bouncycastle.util.Arrays; public class MLKEMKeyGeneratorSpi - extends KeyGeneratorSpi + extends KeyGeneratorSpi { + private final MLKEMParameters mlkemParameters; + private KEMGenerateSpec genSpec; private SecureRandom random; private KEMExtractSpec extSpec; - private MLKEMParameters kyberParameters; public MLKEMKeyGeneratorSpi() { this(null); } - protected MLKEMKeyGeneratorSpi(MLKEMParameters kyberParameters) + protected MLKEMKeyGeneratorSpi(MLKEMParameters mlkemParameters) { - this.kyberParameters = kyberParameters; + this.mlkemParameters = mlkemParameters; } protected void engineInit(SecureRandom secureRandom) @@ -50,9 +52,9 @@ protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec, SecureR { this.genSpec = (KEMGenerateSpec)algorithmParameterSpec; this.extSpec = null; - if (kyberParameters != null) + if (mlkemParameters != null) { - String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName(); + String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName(); if (!canonicalAlgName.equals(genSpec.getPublicKey().getAlgorithm())) { throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); @@ -63,9 +65,9 @@ else if (algorithmParameterSpec instanceof KEMExtractSpec) { this.genSpec = null; this.extSpec = (KEMExtractSpec)algorithmParameterSpec; - if (kyberParameters != null) + if (mlkemParameters != null) { - String canonicalAlgName = MLKEMParameterSpec.fromName(kyberParameters.getName()).getName(); + String canonicalAlgName = MLKEMParameterSpec.fromName(mlkemParameters.getName()).getName(); if (!canonicalAlgName.equals(extSpec.getPrivateKey().getAlgorithm())) { throw new InvalidAlgorithmParameterException("key generator locked to " + canonicalAlgName); @@ -92,24 +94,26 @@ protected SecretKey engineGenerateKey() SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(pubKey.getKeyParams()); - byte[] sharedSecret = secEnc.getSecret(); - - byte[] secret = KdfUtil.makeKeyBytes(genSpec, sharedSecret); - - Arrays.clear(sharedSecret); - - SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, genSpec.getKeyAlgorithmName()), secEnc.getEncapsulation()); + byte[] kemSecret = secEnc.getSecret(); + byte[] kdfSecret = KdfUtil.makeKeyBytes(genSpec, kemSecret); try { - secEnc.destroy(); + SecretKeySpec secretKey = new SecretKeySpec(kdfSecret, genSpec.getKeyAlgorithmName()); + + return new SecretKeyWithEncapsulation(secretKey, secEnc.getEncapsulation()); } - catch (Exception e) + finally { - throw new IllegalStateException("key cleanup failed"); + try + { + secEnc.destroy(); + } + catch (DestroyFailedException e) + { + // ignore + } } - - return rv; } else { @@ -117,16 +121,21 @@ protected SecretKey engineGenerateKey() MLKEMExtractor kemExt = new MLKEMExtractor(privKey.getKeyParams()); byte[] encapsulation = extSpec.getEncapsulation(); - byte[] sharedSecret = kemExt.extractSecret(encapsulation); - byte[] secret = KdfUtil.makeKeyBytes(extSpec, sharedSecret); - Arrays.clear(sharedSecret); + byte[] kemSecret = kemExt.extractSecret(encapsulation); + byte[] kdfSecret = KdfUtil.makeKeyBytes(extSpec, kemSecret); - SecretKey rv = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, extSpec.getKeyAlgorithmName()), encapsulation); - - Arrays.clear(secret); + try + { + SecretKeySpec secretKey = new SecretKeySpec(kdfSecret, extSpec.getKeyAlgorithmName()); - return rv; + // TODO Why do we return ...WithEncapsulation?? + return new SecretKeyWithEncapsulation(secretKey, encapsulation); + } + finally + { + Arrays.clear(kdfSecret); + } } } diff --git a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index 1e0caa1828..bbdc1b21d8 100644 --- a/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/prov/src/main/jdk1.3/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -1214,7 +1214,7 @@ private boolean isAEADModeName( * The ciphers that inherit from us. */ - static private interface GenericBlockCipher + private static interface GenericBlockCipher { public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java index e5f472ead6..d69b4188de 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/GMKeyPairGeneratorSpi.java @@ -46,7 +46,7 @@ public static class BaseSM2 String algorithm; ProviderConfiguration configuration; - static private Hashtable ecParameters; + private static final Hashtable ecParameters; static { diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java index 2ca2c524c8..5c7f9e6c59 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java @@ -50,7 +50,7 @@ public static class EC String algorithm; ProviderConfiguration configuration; - static private Hashtable ecParameters; + private static final Hashtable ecParameters; static { ecParameters = new Hashtable(); diff --git a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index d461361cd9..9b17d648e6 100644 --- a/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/prov/src/main/jdk1.4/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -1294,7 +1294,7 @@ private boolean isAEADModeName( * The ciphers that inherit from us. */ - static private interface GenericBlockCipher + private static interface GenericBlockCipher { public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; diff --git a/prov/src/main/jdk1.5/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/prov/src/main/jdk1.5/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index 5ccc3eb33a..8487dd341f 100644 --- a/prov/src/main/jdk1.5/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/prov/src/main/jdk1.5/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -1317,7 +1317,7 @@ private boolean isAEADModeName( * The ciphers that inherit from us. */ - static private interface GenericBlockCipher + private static interface GenericBlockCipher { public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException; diff --git a/prov/src/main/jdk1.9/module-info.java b/prov/src/main/jdk1.9/module-info.java index c8d1e1cd44..3e000a9c79 100644 --- a/prov/src/main/jdk1.9/module-info.java +++ b/prov/src/main/jdk1.9/module-info.java @@ -15,6 +15,7 @@ opens org.bouncycastle.pqc.jcajce.provider.dilithium to java.base; opens org.bouncycastle.pqc.jcajce.provider.mayo to java.base; opens org.bouncycastle.pqc.jcajce.provider.snova to java.base; + opens org.bouncycastle.pqc.jcajce.provider.ntruplus to java.base; exports org.bouncycastle; exports org.bouncycastle.asn1; @@ -132,6 +133,7 @@ exports org.bouncycastle.pqc.crypto.mayo; exports org.bouncycastle.pqc.crypto.newhope; exports org.bouncycastle.pqc.crypto.ntru; + exports org.bouncycastle.pqc.crypto.ntruplus; exports org.bouncycastle.pqc.crypto.ntruprime; exports org.bouncycastle.pqc.crypto.picnic; exports org.bouncycastle.pqc.crypto.rainbow; @@ -156,6 +158,7 @@ exports org.bouncycastle.pqc.jcajce.provider.lms; exports org.bouncycastle.pqc.jcajce.provider.mayo; exports org.bouncycastle.pqc.jcajce.provider.ntru; + exports org.bouncycastle.pqc.jcajce.provider.ntruplus; exports org.bouncycastle.pqc.jcajce.provider.ntruprime; exports org.bouncycastle.pqc.jcajce.provider.newhope; exports org.bouncycastle.pqc.jcajce.provider.picnic; diff --git a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java b/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java deleted file mode 100644 index b9013ee4b6..0000000000 --- a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/MLKEM.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.bouncycastle.jcajce.provider.asymmetric; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; -import org.bouncycastle.jcajce.provider.asymmetric.mlkem.MLKEMKeyFactorySpi; -import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; - -public class MLKEM -{ - private static final String PREFIX = "org.bouncycastle.jcajce.provider.asymmetric" + ".mlkem."; - - public static class Mappings - extends AsymmetricAlgorithmProvider - { - public Mappings() - { - } - - public void configure(ConfigurableProvider provider) - { - provider.addAlgorithm("KeyFactory.ML-KEM", PREFIX + "MLKEMKeyFactorySpi"); - provider.addAlgorithm("Alg.Alias.KeyFactory.MLKEM", "ML-KEM"); - - addKeyFactoryAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyFactorySpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512, new MLKEMKeyFactorySpi.MLKEM512()); - addKeyFactoryAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyFactorySpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768, new MLKEMKeyFactorySpi.MLKEM768()); - addKeyFactoryAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyFactorySpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024, new MLKEMKeyFactorySpi.MLKEM1024()); - - provider.addAlgorithm("KeyPairGenerator.ML-KEM", PREFIX + "MLKEMKeyPairGeneratorSpi"); - provider.addAlgorithm("Alg.Alias.KeyPairGenerator.MLKEM", "ML-KEM"); - - addKeyPairGeneratorAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); - addKeyPairGeneratorAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); - addKeyPairGeneratorAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyPairGeneratorSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); - - provider.addAlgorithm("KeyGenerator.ML-KEM", PREFIX + "MLKEMKeyGeneratorSpi"); - - addKeyGeneratorAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); - addKeyGeneratorAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); - addKeyGeneratorAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMKeyGeneratorSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); - - AsymmetricKeyInfoConverter keyFact = new MLKEMKeyFactorySpi(); - - provider.addAlgorithm("Cipher.ML-KEM", PREFIX + "MLKEMCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher.MLKEM", "ML-KEM"); - - addCipherAlgorithm(provider, "ML-KEM-512", PREFIX + "MLKEMCipherSpi$MLKEM512", NISTObjectIdentifiers.id_alg_ml_kem_512); - addCipherAlgorithm(provider, "ML-KEM-768", PREFIX + "MLKEMCipherSpi$MLKEM768", NISTObjectIdentifiers.id_alg_ml_kem_768); - addCipherAlgorithm(provider, "ML-KEM-1024", PREFIX + "MLKEMCipherSpi$MLKEM1024", NISTObjectIdentifiers.id_alg_ml_kem_1024); - - provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_512, keyFact); - provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_768, keyFact); - provider.addKeyInfoConverter(NISTObjectIdentifiers.id_alg_ml_kem_1024, keyFact); - - provider.addAlgorithm("KEM.ML-KEM", PREFIX + "MLKEMSpi"); - provider.addAlgorithm("Alg.Alias.KEM." + NISTObjectIdentifiers.id_alg_ml_kem_512, "ML-KEM"); - provider.addAlgorithm("Alg.Alias.KEM." + NISTObjectIdentifiers.id_alg_ml_kem_768, "ML-KEM"); - provider.addAlgorithm("Alg.Alias.KEM." + NISTObjectIdentifiers.id_alg_ml_kem_1024, "ML-KEM"); - } - } -} diff --git a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMDecapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMDecapsulatorSpi.java index 30f3e94f99..619e8965e2 100644 --- a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMDecapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMDecapsulatorSpi.java @@ -1,35 +1,39 @@ package org.bouncycastle.jcajce.provider.asymmetric.mlkem; -import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPrivateKey; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; -import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import java.util.Objects; import javax.crypto.DecapsulateException; import javax.crypto.KEMSpi; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.util.Arrays; -import java.util.Objects; -public class MLKEMDecapsulatorSpi +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; +import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import org.bouncycastle.util.Arrays; + +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ +class MLKEMDecapsulatorSpi implements KEMSpi.DecapsulatorSpi { - BCMLKEMPrivateKey privateKey; - KTSParameterSpec parameterSpec; - MLKEMExtractor kemExt; +// private final BCMLKEMPrivateKey privateKey; + private final KTSParameterSpec parameterSpec; + private final MLKEMExtractor kemExt; - public MLKEMDecapsulatorSpi(BCMLKEMPrivateKey privateKey, KTSParameterSpec parameterSpec) + MLKEMDecapsulatorSpi(BCMLKEMPrivateKey privateKey, KTSParameterSpec parameterSpec) { - this.privateKey = privateKey; +// this.privateKey = privateKey; this.parameterSpec = parameterSpec; - this.kemExt = new MLKEMExtractor(privateKey.getKeyParams()); } @Override - public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) throws DecapsulateException + public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) + throws DecapsulateException { Objects.checkFromToIndex(from, to, engineSecretSize()); Objects.requireNonNull(algorithm, "null algorithm"); @@ -40,28 +44,32 @@ public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, Strin throw new DecapsulateException("incorrect encapsulation size"); } - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - algorithm = parameterSpec.getKeyAlgorithmName(); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + byte[] kemSecret = kemExt.extractSecret(encapsulation); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + + try { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + return new SecretKeySpec(kdfSecret, from, to - from, algorithm); + } + finally + { + Arrays.clear(kdfSecret); } - - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided - boolean useKDF = parameterSpec.getKdfAlgorithm() != null; - - byte[] secret = kemExt.extractSecret(encapsulation); - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - - return new SecretKeySpec(secretKey, algorithm); } @Override diff --git a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMEncapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMEncapsulatorSpi.java index 4f453da7ae..b7a4265a73 100644 --- a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMEncapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMEncapsulatorSpi.java @@ -1,66 +1,75 @@ package org.bouncycastle.jcajce.provider.asymmetric.mlkem; -import org.bouncycastle.crypto.SecretWithEncapsulation; -import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPublicKey; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; -import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import java.security.SecureRandom; +import java.util.Objects; import javax.crypto.KEM; import javax.crypto.KEMSpi; +import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Objects; -public class MLKEMEncapsulatorSpi +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator; +import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import org.bouncycastle.util.Arrays; + +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ +class MLKEMEncapsulatorSpi implements KEMSpi.EncapsulatorSpi { private final BCMLKEMPublicKey publicKey; private final KTSParameterSpec parameterSpec; private final MLKEMGenerator kemGen; - public MLKEMEncapsulatorSpi(BCMLKEMPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) + MLKEMEncapsulatorSpi(BCMLKEMPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) { this.publicKey = publicKey; this.parameterSpec = parameterSpec; - this.kemGen = new MLKEMGenerator(random); } - @Override public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) { Objects.checkFromToIndex(from, to, engineSecretSize()); Objects.requireNonNull(algorithm, "null algorithm"); - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) - { - algorithm = parameterSpec.getKeyAlgorithmName(); - } - - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided - boolean useKDF = parameterSpec.getKdfAlgorithm() != null; - SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(publicKey.getKeyParams()); byte[] encapsulation = secEnc.getEncapsulation(); - byte[] secret = secEnc.getSecret(); - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - return new KEM.Encapsulated(new SecretKeySpec(secretKey, algorithm), encapsulation, null); //TODO: DER encoding for params } + byte[] kemSecret = secEnc.getSecret(); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + + try + { + SecretKey secretKey = new SecretKeySpec(kdfSecret, from, to - from, algorithm); + return new KEM.Encapsulated(secretKey, encapsulation, null); + } + finally + { + Arrays.clear(kdfSecret); + } } @Override @@ -69,21 +78,9 @@ public int engineSecretSize() return parameterSpec.getKeySize() / 8; } - @Override public int engineEncapsulationSize() { - //TODO: Maybe make parameterSet public or add getEncapsulationSize() in KEMGenerator.java - switch (publicKey.getKeyParams().getParameters().getName()) - { - case "ML-KEM-512": - return 768; - case "ML-KEM-768": - return 1088; - case "ML-KEM-1024": - return 1568; - default: - return -1; - } + return publicKey.getKeyParams().getParameters().getEncapsulationLength(); } } diff --git a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMSpi.java b/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMSpi.java index db4fed4ff4..a8b89c048e 100644 --- a/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/jcajce/provider/asymmetric/mlkem/MLKEMSpi.java @@ -1,10 +1,5 @@ package org.bouncycastle.jcajce.provider.asymmetric.mlkem; -import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPrivateKey; -import org.bouncycastle.jcajce.provider.asymmetric.mlkem.BCMLKEMPublicKey; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; - -import javax.crypto.KEMSpi; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.PrivateKey; @@ -12,50 +7,108 @@ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; -public class MLKEMSpi +import javax.crypto.KEMSpi; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyParameters; +import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; + +public abstract class MLKEMSpi implements KEMSpi { + private final MLKEMParameters mlkemParameters; + + MLKEMSpi(MLKEMParameters mlkemParameters) + { + this.mlkemParameters = mlkemParameters; + } + @Override - public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, SecureRandom secureRandom) - throws InvalidAlgorithmParameterException, InvalidKeyException + public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, + SecureRandom secureRandom) throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(publicKey instanceof BCMLKEMPublicKey)) + if (!(publicKey instanceof BCMLKEMPublicKey bcPublicKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPublicKey.getKeyParams()); + if (spec == null) { // Do not wrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) - { - throw new InvalidAlgorithmParameterException("MLKEM can only accept KTSParameterSpec"); - } - if (secureRandom == null) + else if (!(spec instanceof KTSParameterSpec)) { - secureRandom = new SecureRandom(); + throw new InvalidAlgorithmParameterException("ML-KEM can only accept KTSParameterSpec"); } - return new MLKEMEncapsulatorSpi((BCMLKEMPublicKey) publicKey, (KTSParameterSpec) spec, secureRandom); + + return new MLKEMEncapsulatorSpi(bcPublicKey, (KTSParameterSpec)spec, secureRandom); } @Override public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) - throws InvalidAlgorithmParameterException, InvalidKeyException + throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(privateKey instanceof BCMLKEMPrivateKey)) + if (!(privateKey instanceof BCMLKEMPrivateKey bcPrivateKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPrivateKey.getKeyParams()); + if (spec == null) { // Do not unwrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) + else if (!(spec instanceof KTSParameterSpec)) + { + throw new InvalidAlgorithmParameterException("ML-KEM can only accept KTSParameterSpec"); + } + + return new MLKEMDecapsulatorSpi(bcPrivateKey, (KTSParameterSpec)spec); + } + + private void checkKeyParameters(MLKEMKeyParameters key) throws InvalidKeyException + { + if (mlkemParameters != null && mlkemParameters != key.getParameters()) + { + throw new InvalidKeyException("ML-KEM key mismatch"); + } + } + + public static class MLKEM extends MLKEMSpi + { + public MLKEM() + { + // NOTE: Unrestricted parameters/keys + super(null); + } + } + + public static class MLKEM512 extends MLKEMSpi + { + public MLKEM512() + { + super(MLKEMParameters.ml_kem_512); + } + } + + public static class MLKEM768 extends MLKEMSpi + { + public MLKEM768() + { + super(MLKEMParameters.ml_kem_768); + } + } + + public static class MLKEM1024 extends MLKEMSpi + { + public MLKEM1024() { - throw new InvalidAlgorithmParameterException("MLKEM can only accept KTSParameterSpec"); + super(MLKEMParameters.ml_kem_1024); } - return new MLKEMDecapsulatorSpi((BCMLKEMPrivateKey) privateKey, (KTSParameterSpec) spec); } } diff --git a/prov/src/main/jdk17/org/bouncycastle/jcajce/util/SpiUtil.java b/prov/src/main/jdk17/org/bouncycastle/jcajce/util/SpiUtil.java new file mode 100644 index 0000000000..dacd6a5d22 --- /dev/null +++ b/prov/src/main/jdk17/org/bouncycastle/jcajce/util/SpiUtil.java @@ -0,0 +1,15 @@ +package org.bouncycastle.jcajce.util; + +public abstract class SpiUtil +{ + public static boolean hasKDF() + { + return false; + } + + public static boolean hasKEM() + { + // TODO Dynamic check for javax.crypto.KEMSpi (added in 21 and backported to 17 MR 1) + return true; + } +} diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/HQC.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/HQC.java deleted file mode 100644 index c501d1637f..0000000000 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/HQC.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.bouncycastle.pqc.jcajce.provider; - -import org.bouncycastle.asn1.bc.BCObjectIdentifiers; -import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; -import org.bouncycastle.pqc.jcajce.provider.hqc.HQCKeyFactorySpi; - -public class HQC -{ - private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".hqc."; - - public static class Mappings - extends AsymmetricAlgorithmProvider - { - public Mappings() - { - } - - public void configure(ConfigurableProvider provider) - { - provider.addAlgorithm("KeyFactory.HQC", PREFIX + "HQCKeyFactorySpi"); - provider.addAlgorithm("Alg.Alias.KeyFactory.HQC", "HQC"); - addKeyFactoryAlgorithm(provider, "HQC128", PREFIX + "HQCKeyFactorySpi$HQC128", BCObjectIdentifiers.hqc128, new HQCKeyFactorySpi.HQC128()); - addKeyFactoryAlgorithm(provider, "HQC192", PREFIX + "HQCKeyFactorySpi$HQC192", BCObjectIdentifiers.hqc192, new HQCKeyFactorySpi.HQC192()); - addKeyFactoryAlgorithm(provider, "HQC256", PREFIX + "HQCKeyFactorySpi$HQC256", BCObjectIdentifiers.hqc256, new HQCKeyFactorySpi.HQC256()); - - provider.addAlgorithm("KeyPairGenerator.HQC", PREFIX + "HQCKeyPairGeneratorSpi"); - provider.addAlgorithm("Alg.Alias.KeyPairGenerator.HQC", "HQC"); - addKeyPairGeneratorAlgorithm(provider, "HQC128", PREFIX + "HQCKeyPairGeneratorSpi$HQC128", BCObjectIdentifiers.hqc128); - addKeyPairGeneratorAlgorithm(provider, "HQC192", PREFIX + "HQCKeyPairGeneratorSpi$HQC192", BCObjectIdentifiers.hqc192); - addKeyPairGeneratorAlgorithm(provider, "HQC256", PREFIX + "HQCKeyPairGeneratorSpi$HQC256", BCObjectIdentifiers.hqc256); - - provider.addAlgorithm("KeyGenerator.HQC", PREFIX + "HQCKeyGeneratorSpi"); - addKeyGeneratorAlgorithm(provider, "HQC128", PREFIX + "HQCKeyGeneratorSpi$HQC128", BCObjectIdentifiers.hqc128); - addKeyGeneratorAlgorithm(provider, "HQC192", PREFIX + "HQCKeyGeneratorSpi$HQC192", BCObjectIdentifiers.hqc192); - addKeyGeneratorAlgorithm(provider, "HQC256", PREFIX + "HQCKeyGeneratorSpi$HQC256", BCObjectIdentifiers.hqc256); - - AsymmetricKeyInfoConverter keyFact = new HQCKeyFactorySpi(); - - provider.addAlgorithm("Cipher.HQC", PREFIX + "HQCCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher.HQC", "HQC"); - - addCipherAlgorithm(provider, "HQC128", PREFIX + "HQCCipherSpi$HQC128", BCObjectIdentifiers.hqc128); - addCipherAlgorithm(provider, "HQC192", PREFIX + "HQCCipherSpi$HQC192", BCObjectIdentifiers.hqc192); - addCipherAlgorithm(provider, "HQC256", PREFIX + "HQCCipherSpi$HQC256", BCObjectIdentifiers.hqc256); - - provider.addKeyInfoConverter(BCObjectIdentifiers.hqc128, keyFact); - provider.addKeyInfoConverter(BCObjectIdentifiers.hqc192, keyFact); - provider.addKeyInfoConverter(BCObjectIdentifiers.hqc256, keyFact); - - provider.addAlgorithm("KEM.HQC", PREFIX + "HQCKEMSpi"); - provider.addAlgorithm("Alg.Alias.KEM." + BCObjectIdentifiers.hqc128, "HQC"); - provider.addAlgorithm("Alg.Alias.KEM." + BCObjectIdentifiers.hqc192, "HQC"); - provider.addAlgorithm("Alg.Alias.KEM." + BCObjectIdentifiers.hqc256, "HQC"); - } - } -} diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/NTRU.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/NTRU.java deleted file mode 100644 index aa4377f28f..0000000000 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/NTRU.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.bouncycastle.pqc.jcajce.provider; - -import org.bouncycastle.asn1.bc.BCObjectIdentifiers; -import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; -import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUKeyFactorySpi; - -public class NTRU -{ - private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".ntru."; - - public static class Mappings - extends AsymmetricAlgorithmProvider - { - public Mappings() - { - } - - public void configure(ConfigurableProvider provider) - { - provider.addAlgorithm("KeyFactory.NTRU", PREFIX + "NTRUKeyFactorySpi"); - provider.addAlgorithm("KeyPairGenerator.NTRU", PREFIX + "NTRUKeyPairGeneratorSpi"); - - provider.addAlgorithm("KeyGenerator.NTRU", PREFIX + "NTRUKeyGeneratorSpi"); - - AsymmetricKeyInfoConverter keyFact = new NTRUKeyFactorySpi(); - - provider.addAlgorithm("Cipher.NTRU", PREFIX + "NTRUCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntru, "NTRU"); - - registerOid(provider, BCObjectIdentifiers.ntruhps2048509, "NTRU", keyFact); - registerOid(provider, BCObjectIdentifiers.ntruhps2048677, "NTRU", keyFact); - registerOid(provider, BCObjectIdentifiers.ntruhps4096821, "NTRU", keyFact); - registerOid(provider, BCObjectIdentifiers.ntruhps40961229, "NTRU", keyFact); - registerOid(provider, BCObjectIdentifiers.ntruhrss701, "NTRU", keyFact); - registerOid(provider, BCObjectIdentifiers.ntruhrss1373, "NTRU", keyFact); - - provider.addAlgorithm("Kem.NTRU", PREFIX + "NTRUKEMSpi"); - provider.addAlgorithm("Alg.Alias.Kem." + BCObjectIdentifiers.pqc_kem_ntru, "NTRU"); - } - } -} \ No newline at end of file diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java deleted file mode 100644 index 3501d6e969..0000000000 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/NTRUPrime.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.bouncycastle.pqc.jcajce.provider; - -import org.bouncycastle.asn1.bc.BCObjectIdentifiers; -import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider; -import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; -import org.bouncycastle.pqc.jcajce.provider.ntruprime.NTRULPRimeKeyFactorySpi; -import org.bouncycastle.pqc.jcajce.provider.ntruprime.SNTRUPrimeKeyFactorySpi; - -public class NTRUPrime -{ - private static final String PREFIX = "org.bouncycastle.pqc.jcajce.provider" + ".ntruprime."; - - public static class Mappings - extends AsymmetricAlgorithmProvider - { - public Mappings() - { - } - - public void configure(ConfigurableProvider provider) - { - provider.addAlgorithm("KeyFactory.NTRULPRIME", PREFIX + "NTRULPRimeKeyFactorySpi"); - provider.addAlgorithm("KeyPairGenerator.NTRULPRIME", PREFIX + "NTRULPRimeKeyPairGeneratorSpi"); - - provider.addAlgorithm("KeyGenerator.NTRULPRIME", PREFIX + "NTRULPRimeKeyGeneratorSpi"); - - AsymmetricKeyInfoConverter keyFact = new NTRULPRimeKeyFactorySpi(); - - provider.addAlgorithm("Cipher.NTRULPRIME", PREFIX + "NTRULPRimeCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_ntrulprime, "NTRU"); - - registerOid(provider, BCObjectIdentifiers.ntrulpr653, "NTRULPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.ntrulpr761, "NTRULPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.ntrulpr857, "NTRULPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.ntrulpr953, "NTRULPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.ntrulpr1013, "NTRULPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.ntrulpr1277, "NTRULPRIME", keyFact); - - provider.addAlgorithm("KeyFactory.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyFactorySpi"); - provider.addAlgorithm("KeyPairGenerator.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyPairGeneratorSpi"); - - provider.addAlgorithm("KeyGenerator.SNTRUPRIME", PREFIX + "SNTRUPrimeKeyGeneratorSpi"); - - keyFact = new SNTRUPrimeKeyFactorySpi(); - - provider.addAlgorithm("Cipher.SNTRUPRIME", PREFIX + "SNTRUPrimeCipherSpi$Base"); - provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.pqc_kem_sntruprime, "NTRU"); - - registerOid(provider, BCObjectIdentifiers.sntrup653, "SNTRUPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.sntrup761, "SNTRUPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.sntrup857, "SNTRUPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.sntrup953, "SNTRUPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.sntrup1013, "SNTRUPRIME", keyFact); - registerOid(provider, BCObjectIdentifiers.sntrup1277, "SNTRUPRIME", keyFact); - - provider.addAlgorithm("Kem.SNTRUPRIME", PREFIX + "SNTRUPrimeKEMSpi"); - provider.addAlgorithm("Alg.Alias.Kem." + BCObjectIdentifiers.pqc_kem_sntruprime, "SNTRUPRIME"); - } - } -} \ No newline at end of file diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCDecapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCDecapsulatorSpi.java index c5cb327ac1..b0861b5351 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCDecapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCDecapsulatorSpi.java @@ -1,31 +1,33 @@ package org.bouncycastle.pqc.jcajce.provider.hqc; -import org.bouncycastle.pqc.jcajce.provider.hqc.BCHQCPrivateKey; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; - -import org.bouncycastle.pqc.crypto.hqc.HQCKEMExtractor; -import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import java.util.Objects; import javax.crypto.DecapsulateException; import javax.crypto.KEMSpi; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.util.Arrays; -import java.util.Objects; - -public class HQCDecapsulatorSpi +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.hqc.HQCKEMExtractor; +import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import org.bouncycastle.util.Arrays; + +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ +class HQCDecapsulatorSpi implements KEMSpi.DecapsulatorSpi { - BCHQCPrivateKey privateKey; - KTSParameterSpec parameterSpec; - HQCKEMExtractor kemExt; +// private final BCHQCPrivateKey privateKey; + private final KTSParameterSpec parameterSpec; + private final HQCKEMExtractor kemExt; - public HQCDecapsulatorSpi(BCHQCPrivateKey privateKey, KTSParameterSpec parameterSpec) + HQCDecapsulatorSpi(BCHQCPrivateKey privateKey, KTSParameterSpec parameterSpec) { - this.privateKey = privateKey; +// this.privateKey = privateKey; this.parameterSpec = parameterSpec; - this.kemExt = new HQCKEMExtractor(privateKey.getKeyParams()); } @@ -42,28 +44,32 @@ public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, Strin throw new DecapsulateException("incorrect encapsulation size"); } - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - algorithm = parameterSpec.getKeyAlgorithmName(); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + byte[] kemSecret = kemExt.extractSecret(encapsulation); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + + try { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + return new SecretKeySpec(kdfSecret, from, to - from, algorithm); + } + finally + { + Arrays.clear(kdfSecret); } - - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided - boolean useKDF = parameterSpec.getKdfAlgorithm() != null; - - byte[] secret = kemExt.extractSecret(encapsulation); - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - - return new SecretKeySpec(secretKey, algorithm); } @Override @@ -77,4 +83,4 @@ public int engineEncapsulationSize() { return kemExt.getEncapsulationLength(); } -} \ No newline at end of file +} diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCEncapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCEncapsulatorSpi.java index c3623c4e4a..9fd498df34 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCEncapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCEncapsulatorSpi.java @@ -1,31 +1,35 @@ package org.bouncycastle.pqc.jcajce.provider.hqc; -import org.bouncycastle.crypto.SecretWithEncapsulation; -import org.bouncycastle.pqc.jcajce.provider.hqc.BCHQCPublicKey; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.hqc.HQCKEMGenerator; -import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import java.security.SecureRandom; +import java.util.Objects; import javax.crypto.KEM; import javax.crypto.KEMSpi; +import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Objects; +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.hqc.HQCKEMGenerator; +import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import org.bouncycastle.util.Arrays; -public class HQCEncapsulatorSpi +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ +class HQCEncapsulatorSpi implements KEMSpi.EncapsulatorSpi { private final BCHQCPublicKey publicKey; private final KTSParameterSpec parameterSpec; private final HQCKEMGenerator kemGen; - public HQCEncapsulatorSpi(BCHQCPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) + HQCEncapsulatorSpi(BCHQCPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) { this.publicKey = publicKey; this.parameterSpec = parameterSpec; - this.kemGen = new HQCKEMGenerator(random); } @@ -35,31 +39,37 @@ public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) Objects.checkFromToIndex(from, to, engineSecretSize()); Objects.requireNonNull(algorithm, "null algorithm"); - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) - { - algorithm = parameterSpec.getKeyAlgorithmName(); - } - - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided - boolean useKDF = parameterSpec.getKdfAlgorithm() != null; - SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(publicKey.getKeyParams()); byte[] encapsulation = secEnc.getEncapsulation(); - byte[] secret = secEnc.getSecret(); - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - return new KEM.Encapsulated(new SecretKeySpec(secretKey, algorithm), encapsulation, null); //TODO: DER encoding for params + byte[] kemSecret = secEnc.getSecret(); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + + try + { + SecretKey secretKey = new SecretKeySpec(kdfSecret, from, to - from, algorithm); + return new KEM.Encapsulated(secretKey, encapsulation, null); + } + finally + { + Arrays.clear(kdfSecret); + } } @Override @@ -71,17 +81,6 @@ public int engineSecretSize() @Override public int engineEncapsulationSize() { - //TODO: Maybe make parameterSet public or add getEncapsulationSize() in HQCKEMGenerator.java - switch (publicKey.getKeyParams().getParameters().getName()) - { - case "HQC-128": - return 128; - case "HQC-192": - return 192; - case "HQC-256": - return 256; - default: - return -1; - } + return publicKey.getKeyParams().getParameters().getEncapsulationLength(); } -} \ No newline at end of file +} diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCKEMSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCKEMSpi.java index 329ef16f2f..6057bd9c43 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCKEMSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/hqc/HQCKEMSpi.java @@ -10,53 +10,105 @@ import javax.crypto.KEMSpi; import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.hqc.HQCKeyParameters; +import org.bouncycastle.pqc.crypto.hqc.HQCParameters; -public class HQCKEMSpi +public abstract class HQCKEMSpi implements KEMSpi { + private final HQCParameters hqcParameters; + + HQCKEMSpi(HQCParameters hqcParameters) + { + this.hqcParameters = hqcParameters; + } @Override public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, - SecureRandom secureRandom) - throws InvalidAlgorithmParameterException, InvalidKeyException + SecureRandom secureRandom) throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(publicKey instanceof BCHQCPublicKey)) + if (!(publicKey instanceof BCHQCPublicKey bcPublicKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPublicKey.getKeyParams()); + if (spec == null) { // Do not wrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) + else if (!(spec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException("HQC can only accept KTSParameterSpec"); } - if (secureRandom == null) - { - secureRandom = new SecureRandom(); - } - return new HQCEncapsulatorSpi((BCHQCPublicKey)publicKey, (KTSParameterSpec)spec, secureRandom); + + return new HQCEncapsulatorSpi(bcPublicKey, (KTSParameterSpec)spec, secureRandom); } @Override public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(privateKey instanceof BCHQCPrivateKey)) + if (!(privateKey instanceof BCHQCPrivateKey bcPrivateKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPrivateKey.getKeyParams()); + if (spec == null) { // Do not unwrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) + else if (!(spec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException("HQC can only accept KTSParameterSpec"); } - return new HQCDecapsulatorSpi((BCHQCPrivateKey)privateKey, (KTSParameterSpec)spec); + + return new HQCDecapsulatorSpi(bcPrivateKey, (KTSParameterSpec)spec); + } + + private void checkKeyParameters(HQCKeyParameters key) throws InvalidKeyException + { + if (hqcParameters != null && hqcParameters != key.getParameters()) + { + throw new InvalidKeyException("HQC key mismatch"); + } + } + + public static class HQC extends HQCKEMSpi + { + public HQC() + { + // NOTE: Unrestricted parameters/keys + super(null); + } + } + + public static class HQC128 extends HQCKEMSpi + { + public HQC128() + { + super(HQCParameters.hqc128); + } + } + + public static class HQC192 extends HQCKEMSpi + { + public HQC192() + { + super(HQCParameters.hqc192); + } + } + + public static class HQC256 extends HQCKEMSpi + { + public HQC256() + { + super(HQCParameters.hqc256); + } } -} \ No newline at end of file +} diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUDecapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUDecapsulatorSpi.java index 71c174efa9..823e2dffc2 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUDecapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUDecapsulatorSpi.java @@ -1,36 +1,39 @@ package org.bouncycastle.pqc.jcajce.provider.ntru; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; - -import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.ntru.NTRUKEMExtractor; -import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import java.util.Objects; import javax.crypto.DecapsulateException; import javax.crypto.KEMSpi; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.util.Arrays; -import java.util.Objects; -public class NTRUDecapsulatorSpi +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntru.NTRUKEMExtractor; +import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import org.bouncycastle.util.Arrays; + +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ +class NTRUDecapsulatorSpi implements KEMSpi.DecapsulatorSpi { - BCNTRUPrivateKey privateKey; - KTSParameterSpec parameterSpec; - NTRUKEMExtractor kemExt; +// private final BCNTRUPrivateKey privateKey; + private final KTSParameterSpec parameterSpec; + private final NTRUKEMExtractor kemExt; - public NTRUDecapsulatorSpi(BCNTRUPrivateKey privateKey, KTSParameterSpec parameterSpec) + NTRUDecapsulatorSpi(BCNTRUPrivateKey privateKey, KTSParameterSpec parameterSpec) { - this.privateKey = privateKey; +// this.privateKey = privateKey; this.parameterSpec = parameterSpec; - this.kemExt = new NTRUKEMExtractor(privateKey.getKeyParams()); } @Override - public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) throws DecapsulateException + public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) + throws DecapsulateException { Objects.checkFromToIndex(from, to, engineSecretSize()); Objects.requireNonNull(algorithm, "null algorithm"); @@ -41,28 +44,32 @@ public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, Strin throw new DecapsulateException("incorrect encapsulation size"); } - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - algorithm = parameterSpec.getKeyAlgorithmName(); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + byte[] kemSecret = kemExt.extractSecret(encapsulation); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + + try { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + return new SecretKeySpec(kdfSecret, from, to - from, algorithm); + } + finally + { + Arrays.clear(kdfSecret); } - - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided - boolean useKDF = parameterSpec.getKdfAlgorithm() != null; - - byte[] secret = kemExt.extractSecret(encapsulation); - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - - return new SecretKeySpec(secretKey, algorithm); } @Override diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUEncapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUEncapsulatorSpi.java index fea938b4ee..99fa652516 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUEncapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUEncapsulatorSpi.java @@ -1,30 +1,35 @@ package org.bouncycastle.pqc.jcajce.provider.ntru; -import org.bouncycastle.crypto.SecretWithEncapsulation; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.ntru.NTRUKEMGenerator; -import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import java.security.SecureRandom; +import java.util.Objects; import javax.crypto.KEM; import javax.crypto.KEMSpi; +import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Objects; -public class NTRUEncapsulatorSpi +import org.bouncycastle.crypto.SecretWithEncapsulation; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntru.NTRUKEMGenerator; +import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import org.bouncycastle.util.Arrays; + +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ +class NTRUEncapsulatorSpi implements KEMSpi.EncapsulatorSpi { private final BCNTRUPublicKey publicKey; private final KTSParameterSpec parameterSpec; private final NTRUKEMGenerator kemGen; - public NTRUEncapsulatorSpi(BCNTRUPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) + NTRUEncapsulatorSpi(BCNTRUPublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) { this.publicKey = publicKey; this.parameterSpec = parameterSpec; - this.kemGen = new NTRUKEMGenerator(random); } @@ -34,31 +39,37 @@ public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) Objects.checkFromToIndex(from, to, engineSecretSize()); Objects.requireNonNull(algorithm, "null algorithm"); - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) - { - algorithm = parameterSpec.getKeyAlgorithmName(); - } - - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided - boolean useKDF = parameterSpec.getKdfAlgorithm() != null; - SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(publicKey.getKeyParams()); byte[] encapsulation = secEnc.getEncapsulation(); - byte[] secret = secEnc.getSecret(); - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - return new KEM.Encapsulated(new SecretKeySpec(secretKey, algorithm), encapsulation, null); //TODO: DER encoding for params + byte[] kemSecret = secEnc.getSecret(); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + + try + { + SecretKey secretKey = new SecretKeySpec(kdfSecret, from, to - from, algorithm); + return new KEM.Encapsulated(secretKey, encapsulation, null); + } + finally + { + Arrays.clear(kdfSecret); + } } @Override @@ -70,23 +81,6 @@ public int engineSecretSize() @Override public int engineEncapsulationSize() { - //TODO: Maybe make parameterSet public or add getEncapsulationSize() in NTRUKEMGenerator.java - switch (publicKey.getKeyParams().getParameters().getName()) - { - case "ntruhps2048509": - return 699; - case "ntruhps2048677": - return 930; - case "ntruhps4096821": - return 1230; - case "ntruhps40961229": - return 1843; - case "ntruhrss701": - return 1138; - case "ntruhrss1373": - return 2401; - default: - return -1; - } + return publicKey.getKeyParams().getParameters().getEncapsulationLength(); } } diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKEMSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKEMSpi.java index 77b7a2bf54..0584f2eac5 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKEMSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntru/NTRUKEMSpi.java @@ -1,10 +1,5 @@ package org.bouncycastle.pqc.jcajce.provider.ntru; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.jcajce.provider.ntru.BCNTRUPrivateKey; -import org.bouncycastle.pqc.jcajce.provider.ntru.NTRUDecapsulatorSpi; - -import javax.crypto.KEMSpi; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.PrivateKey; @@ -12,51 +7,84 @@ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; -public class NTRUKEMSpi +import javax.crypto.KEMSpi; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntru.NTRUKeyParameters; +import org.bouncycastle.pqc.crypto.ntru.NTRUParameters; + +public abstract class NTRUKEMSpi implements KEMSpi { + private final NTRUParameters ntruParameters; + + NTRUKEMSpi(NTRUParameters ntruParameters) + { + this.ntruParameters = ntruParameters; + } @Override - public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, SecureRandom secureRandom) - throws InvalidAlgorithmParameterException, InvalidKeyException + public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, + SecureRandom secureRandom) throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(publicKey instanceof BCNTRUPublicKey)) + if (!(publicKey instanceof BCNTRUPublicKey bcPublicKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPublicKey.getKeyParams()); + if (spec == null) { // Do not wrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) + else if (!(spec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException("NTRU can only accept KTSParameterSpec"); } - if (secureRandom == null) - { - secureRandom = new SecureRandom(); - } - return new NTRUEncapsulatorSpi((BCNTRUPublicKey) publicKey, (KTSParameterSpec) spec, secureRandom); + + return new NTRUEncapsulatorSpi(bcPublicKey, (KTSParameterSpec)spec, secureRandom); } @Override public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) - throws InvalidAlgorithmParameterException, InvalidKeyException + throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(privateKey instanceof BCNTRUPrivateKey)) + if (!(privateKey instanceof BCNTRUPrivateKey bcPrivateKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPrivateKey.getKeyParams()); + if (spec == null) { // Do not unwrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) + else if (!(spec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException("NTRU can only accept KTSParameterSpec"); } - return new NTRUDecapsulatorSpi((BCNTRUPrivateKey) privateKey, (KTSParameterSpec) spec); + + return new NTRUDecapsulatorSpi(bcPrivateKey, (KTSParameterSpec)spec); + } + + private void checkKeyParameters(NTRUKeyParameters key) throws InvalidKeyException + { + if (ntruParameters != null && ntruParameters != key.getParameters()) + { + throw new InvalidKeyException("NTRU key mismatch"); + } + } + + public static class NTRU extends NTRUKEMSpi + { + public NTRU() + { + // NOTE: Unrestricted parameters/keys + super(null); + } } } diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeDecapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeDecapsulatorSpi.java index 945237dca6..45cb048ff9 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeDecapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeDecapsulatorSpi.java @@ -1,35 +1,39 @@ package org.bouncycastle.pqc.jcajce.provider.ntruprime; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; -import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMExtractor; -import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; -import org.bouncycastle.util.Arrays; +import java.util.Objects; import javax.crypto.DecapsulateException; import javax.crypto.KEMSpi; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.util.Objects; +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMExtractor; +import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; +import org.bouncycastle.util.Arrays; + +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ class SNTRUPrimeDecapsulatorSpi implements KEMSpi.DecapsulatorSpi { - BCSNTRUPrimePrivateKey privateKey; - KTSParameterSpec parameterSpec; - - SNTRUPrimeKEMExtractor kemExt; +// private final BCSNTRUPrimePrivateKey privateKey; + private final KTSParameterSpec parameterSpec; + private final SNTRUPrimeKEMExtractor kemExt; - public SNTRUPrimeDecapsulatorSpi(BCSNTRUPrimePrivateKey privateKey, KTSParameterSpec parameterSpec) + SNTRUPrimeDecapsulatorSpi(BCSNTRUPrimePrivateKey privateKey, KTSParameterSpec parameterSpec) { - this.privateKey = privateKey; +// this.privateKey = privateKey; this.parameterSpec = parameterSpec; - - kemExt = new SNTRUPrimeKEMExtractor(privateKey.getKeyParams()); + this.kemExt = new SNTRUPrimeKEMExtractor(privateKey.getKeyParams()); } @Override - public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) throws DecapsulateException + public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, String algorithm) + throws DecapsulateException { Objects.checkFromToIndex(from, to, engineSecretSize()); Objects.requireNonNull(algorithm, "null algorithm"); @@ -40,27 +44,32 @@ public SecretKey engineDecapsulate(byte[] encapsulation, int from, int to, Strin throw new DecapsulateException("incorrect encapsulation size"); } - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - algorithm = parameterSpec.getKeyAlgorithmName(); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + byte[] kemSecret = kemExt.extractSecret(encapsulation); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + + try { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + return new SecretKeySpec(kdfSecret, from, to - from, algorithm); + } + finally + { + Arrays.clear(kdfSecret); } - - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided - byte[] secret = kemExt.extractSecret(encapsulation); - - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - - return new SecretKeySpec(secretKey, algorithm); } @Override diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeEncapsulatorSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeEncapsulatorSpi.java index 13698138a7..f4e60a4cb5 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeEncapsulatorSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeEncapsulatorSpi.java @@ -1,18 +1,24 @@ package org.bouncycastle.pqc.jcajce.provider.ntruprime; +import java.security.SecureRandom; +import java.util.Objects; + +import javax.crypto.KEM; +import javax.crypto.KEMSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + import org.bouncycastle.crypto.SecretWithEncapsulation; import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKEMGenerator; import org.bouncycastle.pqc.jcajce.provider.util.KdfUtil; import org.bouncycastle.util.Arrays; -import javax.crypto.KEM; -import javax.crypto.KEMSpi; -import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.security.SecureRandom; -import java.util.Objects; - +/* + * NOTE: Per javadoc for javax.crypto.KEM, "Encapsulator and Decapsulator objects are also immutable. It is safe to + * invoke multiple encapsulate and decapsulate methods on the same Encapsulator or Decapsulator object at the same + * time. Each invocation of encapsulate will generate a new shared secret and key encapsulation message." + */ class SNTRUPrimeEncapsulatorSpi implements KEMSpi.EncapsulatorSpi { @@ -20,13 +26,11 @@ class SNTRUPrimeEncapsulatorSpi private final KTSParameterSpec parameterSpec; private final SNTRUPrimeKEMGenerator kemGen; - - public SNTRUPrimeEncapsulatorSpi(BCSNTRUPrimePublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) + SNTRUPrimeEncapsulatorSpi(BCSNTRUPrimePublicKey publicKey, KTSParameterSpec parameterSpec, SecureRandom random) { this.publicKey = publicKey; this.parameterSpec = parameterSpec; - - kemGen = new SNTRUPrimeKEMGenerator(random); + this.kemGen = new SNTRUPrimeKEMGenerator(random); } @Override @@ -35,31 +39,37 @@ public KEM.Encapsulated engineEncapsulate(int from, int to, String algorithm) Objects.checkFromToIndex(from, to, engineSecretSize()); Objects.requireNonNull(algorithm, "null algorithm"); - // if algorithm is Generic then use parameterSpec to wrap key - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - algorithm.equals("Generic")) - { - algorithm = parameterSpec.getKeyAlgorithmName(); - } - - // check spec algorithm mismatch provided algorithm - if (!parameterSpec.getKeyAlgorithmName().equals("Generic") && - !parameterSpec.getKeyAlgorithmName().equals(algorithm)) + String keyAlgName = parameterSpec.getKeyAlgorithmName(); + if (!"Generic".equals(keyAlgName)) { - throw new UnsupportedOperationException(parameterSpec.getKeyAlgorithmName() + " does not match " + algorithm); + // if algorithm is Generic then use parameterSpec to wrap key + if ("Generic".equals(algorithm)) + { + algorithm = keyAlgName; + } + // check spec algorithm mismatch provided algorithm + else if (!algorithm.equals(keyAlgName)) + { + throw new UnsupportedOperationException(keyAlgName + " does not match " + algorithm); + } } - // Only use KDF when ktsParameterSpec is provided - // Considering any ktsParameterSpec with "Generic" as ktsParameterSpec not provided SecretWithEncapsulation secEnc = kemGen.generateEncapsulated(publicKey.getKeyParams()); byte[] encapsulation = secEnc.getEncapsulation(); - byte[] secret = secEnc.getSecret(); - byte[] secretKey = Arrays.copyOfRange(KdfUtil.makeKeyBytes(parameterSpec, secret), from, to); - - return new KEM.Encapsulated(new SecretKeySpec(secretKey, algorithm), encapsulation, null); //TODO: DER encoding for params + byte[] kemSecret = secEnc.getSecret(); + byte[] kdfSecret = KdfUtil.makeKeyBytes(parameterSpec, kemSecret); + try + { + SecretKey secretKey = new SecretKeySpec(kdfSecret, from, to - from, algorithm); + return new KEM.Encapsulated(secretKey, encapsulation, null); + } + finally + { + Arrays.clear(kdfSecret); + } } @Override diff --git a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeKEMSpi.java b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeKEMSpi.java index 64be2c116e..4a321664fa 100644 --- a/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeKEMSpi.java +++ b/prov/src/main/jdk17/org/bouncycastle/pqc/jcajce/provider/ntruprime/SNTRUPrimeKEMSpi.java @@ -1,8 +1,5 @@ package org.bouncycastle.pqc.jcajce.provider.ntruprime; -import org.bouncycastle.jcajce.spec.KTSParameterSpec; - -import javax.crypto.KEMSpi; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.PrivateKey; @@ -10,49 +7,84 @@ import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; -public class SNTRUPrimeKEMSpi +import javax.crypto.KEMSpi; + +import org.bouncycastle.jcajce.spec.KTSParameterSpec; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKeyParameters; +import org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters; + +public abstract class SNTRUPrimeKEMSpi implements KEMSpi { + private final SNTRUPrimeParameters sntruPrimeParameters; + + SNTRUPrimeKEMSpi(SNTRUPrimeParameters sntruPrimeParameters) + { + this.sntruPrimeParameters = sntruPrimeParameters; + } @Override - public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, SecureRandom secureRandom) throws InvalidAlgorithmParameterException, InvalidKeyException + public EncapsulatorSpi engineNewEncapsulator(PublicKey publicKey, AlgorithmParameterSpec spec, + SecureRandom secureRandom) throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(publicKey instanceof BCSNTRUPrimePublicKey)) + if (!(publicKey instanceof BCSNTRUPrimePublicKey bcPublicKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPublicKey.getKeyParams()); + if (spec == null) { // Do not wrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) + else if (!(spec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException("SNTRUPrime can only accept KTSParameterSpec"); } - if (secureRandom == null) - { - secureRandom = new SecureRandom(); - } - return new SNTRUPrimeEncapsulatorSpi((BCSNTRUPrimePublicKey) publicKey,(KTSParameterSpec) spec, secureRandom); + + return new SNTRUPrimeEncapsulatorSpi(bcPublicKey, (KTSParameterSpec)spec, secureRandom); } @Override - public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException, InvalidKeyException + public DecapsulatorSpi engineNewDecapsulator(PrivateKey privateKey, AlgorithmParameterSpec spec) + throws InvalidAlgorithmParameterException, InvalidKeyException { - if (!(privateKey instanceof BCSNTRUPrimePrivateKey)) + if (!(privateKey instanceof BCSNTRUPrimePrivateKey bcPrivateKey)) { - throw new InvalidKeyException("unsupported key"); + throw new InvalidKeyException("unsupported key type"); } + + checkKeyParameters(bcPrivateKey.getKeyParams()); + if (spec == null) { // Do not unwrap key, no KDF spec = new KTSParameterSpec.Builder("Generic", 256).withNoKdf().build(); } - if (!(spec instanceof KTSParameterSpec)) + else if (!(spec instanceof KTSParameterSpec)) { throw new InvalidAlgorithmParameterException("SNTRUPrime can only accept KTSParameterSpec"); } - return new SNTRUPrimeDecapsulatorSpi((BCSNTRUPrimePrivateKey) privateKey, (KTSParameterSpec) spec); + + return new SNTRUPrimeDecapsulatorSpi(bcPrivateKey, (KTSParameterSpec)spec); + } + + private void checkKeyParameters(SNTRUPrimeKeyParameters key) throws InvalidKeyException + { + if (sntruPrimeParameters != null && sntruPrimeParameters != key.getParameters()) + { + throw new InvalidKeyException("SNTRUPrime key mismatch"); + } + } + + public static class SNTRUPrime extends SNTRUPrimeKEMSpi + { + public SNTRUPrime() + { + // NOTE: Unrestricted parameters/keys + super(null); + } } } diff --git a/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/HKDF.java b/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/HKDF.java index 54fa8babb8..bcfc2c2a0f 100644 --- a/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/HKDF.java +++ b/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/HKDF.java @@ -4,12 +4,12 @@ import org.bouncycastle.jcajce.provider.config.ConfigurableProvider; import org.bouncycastle.jcajce.provider.util.AlgorithmProvider; -class HKDF +public class HKDF { private static final String PREFIX = "org.bouncycastle.jcajce.provider.kdf" + ".hkdf."; public static class Mappings - extends AlgorithmProvider + extends AlgorithmProvider { public Mappings() { @@ -17,18 +17,19 @@ public Mappings() public void configure(ConfigurableProvider provider) { + /* + * TODO Would need HKDFSpi to be public, have a constructor from KDFParameters, and have some way to + * decide which digest to use. + */ +// provider.addAlgorithm("KDF.HKDF", PREFIX + "HKDFSpi"); - provider.addAlgorithm("KDF.HKDF", PREFIX + "HKDFSpi"); provider.addAlgorithm("KDF.HKDF-SHA256", PREFIX + "HKDFSpi$HKDFwithSHA256"); provider.addAlgorithm("KDF.HKDF-SHA384", PREFIX + "HKDFSpi$HKDFwithSHA384"); provider.addAlgorithm("KDF.HKDF-SHA512", PREFIX + "HKDFSpi$HKDFwithSHA512"); - // Use SymmetricAlgorithmProvider? - //TODO: add PKCSObjectIdentifiers? - //PKCSObjectIdentifiers.id_alg_hkdf_with_sha256 - //PKCSObjectIdentifiers.id_alg_hkdf_with_sha384 - //PKCSObjectIdentifiers.id_alg_hkdf_with_sha512 - + provider.addAlgorithm("Alg.Alias.KDF." + PKCSObjectIdentifiers.id_alg_hkdf_with_sha256, "HKDF-SHA256"); + provider.addAlgorithm("Alg.Alias.KDF." + PKCSObjectIdentifiers.id_alg_hkdf_with_sha384, "HKDF-SHA384"); + provider.addAlgorithm("Alg.Alias.KDF." + PKCSObjectIdentifiers.id_alg_hkdf_with_sha512, "HKDF-SHA512"); } } } diff --git a/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/hkdf/HKDFSpi.java b/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/hkdf/HKDFSpi.java index 023dc4ebd5..bc84721c44 100644 --- a/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/hkdf/HKDFSpi.java +++ b/prov/src/main/jdk25/org/bouncycastle/jcajce/provider/kdf/hkdf/HKDFSpi.java @@ -1,5 +1,17 @@ package org.bouncycastle.jcajce.provider.kdf.hkdf; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.ArrayList; +import java.util.List; + +import javax.crypto.KDFParameters; +import javax.crypto.KDFSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.HKDFParameterSpec; +import javax.crypto.spec.SecretKeySpec; + import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; @@ -8,23 +20,11 @@ import org.bouncycastle.crypto.params.HKDFParameters; import org.bouncycastle.util.Arrays; -import javax.crypto.KDFParameters; -import javax.crypto.KDFSpi; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; -import javax.crypto.spec.HKDFParameterSpec; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.spec.AlgorithmParameterSpec; -import java.util.ArrayList; -import java.util.List; - -class HKDFSpi - extends KDFSpi +public class HKDFSpi extends KDFSpi { - protected HKDFBytesGenerator hkdf; + private final HKDFBytesGenerator hkdf; - public HKDFSpi(KDFParameters kdfParameters, Digest digest) + HKDFSpi(KDFParameters kdfParameters, Digest digest) throws InvalidAlgorithmParameterException { super(requireNull(kdfParameters, "HKDF" + " does not support parameters")); @@ -56,66 +56,73 @@ protected SecretKey engineDeriveKey(String alg, AlgorithmParameterSpec derivatio { byte[] derivedKey = engineDeriveData(derivationSpec); - return new SecretKeySpec(derivedKey, alg); + try + { + return new SecretKeySpec(derivedKey, alg); + } + finally + { + Arrays.clear(derivedKey); + } } + @Override protected byte[] engineDeriveData(AlgorithmParameterSpec derivationSpec) throws InvalidAlgorithmParameterException { - if (derivationSpec == null - || !(derivationSpec instanceof org.bouncycastle.jcajce.spec.HKDFParameterSpec - || derivationSpec instanceof javax.crypto.spec.HKDFParameterSpec)) - { - throw new InvalidAlgorithmParameterException("Invalid AlgorithmParameterSpec provided"); - } - - HKDFParameters hkdfParameters = null; - int derivedDataLength = 0; - if (derivationSpec instanceof HKDFParameterSpec.ExtractThenExpand) + if (derivationSpec instanceof org.bouncycastle.jcajce.spec.HKDFParameterSpec) { - HKDFParameterSpec.ExtractThenExpand spec = (HKDFParameterSpec.ExtractThenExpand)derivationSpec; + org.bouncycastle.jcajce.spec.HKDFParameterSpec spec = (org.bouncycastle.jcajce.spec.HKDFParameterSpec)derivationSpec; - List ikms = spec.ikms(); - List salts = spec.salts(); + byte[] ikm = spec.getIKM(); + byte[] salt = spec.getSalt(); + byte[] info = spec.getInfo(); - byte[] salt = flattenSecretKeys(salts); - byte[] ikm = flattenSecretKeys(ikms); + return expand(spec.getOutputLength(), new HKDFParameters(ikm, salt, info)); + } - hkdfParameters = new HKDFParameters(ikm, salt, spec.info()); - derivedDataLength = spec.length(); + if (!(derivationSpec instanceof HKDFParameterSpec)) + { + throw new InvalidAlgorithmParameterException("Invalid AlgorithmParameterSpec provided"); + } - hkdf.init(hkdfParameters); + if (derivationSpec instanceof HKDFParameterSpec.Expand) + { + HKDFParameterSpec.Expand spec = (HKDFParameterSpec.Expand)derivationSpec; - byte[] derivedData = new byte[derivedDataLength]; - hkdf.generateBytes(derivedData, 0, derivedDataLength); + byte[] ikm = spec.prk().getEncoded(); + byte[] info = spec.info(); - return derivedData; + return expand(spec.length(), HKDFParameters.skipExtractParameters(ikm, info)); } else if (derivationSpec instanceof HKDFParameterSpec.Extract) { HKDFParameterSpec.Extract spec = (HKDFParameterSpec.Extract)derivationSpec; - List ikms = spec.ikms(); - List salts = spec.salts(); - - byte[] salt = flattenSecretKeys(salts); - byte[] ikm = flattenSecretKeys(ikms); + byte[] ikm = flattenSecretKeys(spec.ikms()); + byte[] salt = flattenSecretKeys(spec.salts()); return hkdf.extractPRK(salt, ikm); } - else if (derivationSpec instanceof org.bouncycastle.jcajce.spec.HKDFParameterSpec) + else if (derivationSpec instanceof HKDFParameterSpec.ExtractThenExpand) { - org.bouncycastle.jcajce.spec.HKDFParameterSpec spec = (org.bouncycastle.jcajce.spec.HKDFParameterSpec)derivationSpec; + HKDFParameterSpec.ExtractThenExpand spec = (HKDFParameterSpec.ExtractThenExpand)derivationSpec; - hkdfParameters = new HKDFParameters(spec.getIKM(), spec.getSalt(), spec.getInfo()); - derivedDataLength = spec.getOutputLength(); + byte[] ikm = flattenSecretKeys(spec.ikms()); + byte[] salt = flattenSecretKeys(spec.salts()); + byte[] info = spec.info(); - hkdf.init(hkdfParameters); + return expand(spec.length(), new HKDFParameters(ikm, salt, info)); + } + else if (derivationSpec instanceof org.bouncycastle.jcajce.spec.HKDFParameterSpec) + { + org.bouncycastle.jcajce.spec.HKDFParameterSpec spec = (org.bouncycastle.jcajce.spec.HKDFParameterSpec)derivationSpec; - byte[] derivedData = new byte[derivedDataLength]; - hkdf.generateBytes(derivedData, 0, derivedDataLength); + byte[] ikm = spec.getIKM(); + byte[] salt = spec.getSalt(); + byte[] info = spec.getInfo(); - return derivedData; + return expand(spec.getOutputLength(), new HKDFParameters(ikm, salt, info)); } else { @@ -123,17 +130,16 @@ else if (derivationSpec instanceof org.bouncycastle.jcajce.spec.HKDFParameterSpe } } - private static KDFParameters requireNull(KDFParameters kdfParameters, - String message) throws InvalidAlgorithmParameterException + private byte[] expand(int length, HKDFParameters hkdfParameters) { - if (kdfParameters != null) - { - throw new InvalidAlgorithmParameterException(message); - } - return null; + hkdf.init(hkdfParameters); + + byte[] result = new byte[length]; + hkdf.generateBytes(result, 0, length); + return result; } - private byte[] flattenSecretKeys(List keys) + private static byte[] flattenSecretKeys(List keys) { if (keys.size() == 1) { @@ -161,6 +167,16 @@ private byte[] flattenSecretKeys(List keys) return res; } + private static KDFParameters requireNull(KDFParameters kdfParameters, String message) + throws InvalidAlgorithmParameterException + { + if (kdfParameters != null) + { + throw new InvalidAlgorithmParameterException(message); + } + return null; + } + public static class HKDFwithSHA256 extends HKDFSpi { public HKDFwithSHA256(KDFParameters kdfParameters) throws InvalidAlgorithmParameterException @@ -172,6 +188,7 @@ public HKDFwithSHA256() throws InvalidAlgorithmParameterException this(null); } } + public static class HKDFwithSHA384 extends HKDFSpi { public HKDFwithSHA384(KDFParameters kdfParameters) throws InvalidAlgorithmParameterException @@ -183,9 +200,9 @@ public HKDFwithSHA384() throws InvalidAlgorithmParameterException this(null); } } + public static class HKDFwithSHA512 extends HKDFSpi { - public HKDFwithSHA512(KDFParameters kdfParameters) throws InvalidAlgorithmParameterException { super(kdfParameters, new SHA512Digest()); @@ -195,5 +212,4 @@ public HKDFwithSHA512() throws InvalidAlgorithmParameterException this(null); } } - } diff --git a/prov/src/main/jdk25/org/bouncycastle/jcajce/util/SpiUtil.java b/prov/src/main/jdk25/org/bouncycastle/jcajce/util/SpiUtil.java new file mode 100644 index 0000000000..443908ddf9 --- /dev/null +++ b/prov/src/main/jdk25/org/bouncycastle/jcajce/util/SpiUtil.java @@ -0,0 +1,14 @@ +package org.bouncycastle.jcajce.util; + +public abstract class SpiUtil +{ + public static boolean hasKDF() + { + return true; + } + + public static boolean hasKEM() + { + return true; + } +} diff --git a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java index cc8239bbf4..43245272fe 100644 --- a/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java +++ b/prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java @@ -55,16 +55,6 @@ public class CompositeSignaturesTest extends TestCase { - public static void main(String[] args) - throws Exception - { - CompositeSignaturesTest test = new CompositeSignaturesTest(); - test.setUp(); - List> testVectors = test.readTestVectorsFromJson("pqc/crypto/composite", "testvectors.json"); - test.compositeSignaturesTest(testVectors); - test.testSigningAndVerificationInternal(); - } - private static String[] compositeSignaturesOIDs = { "1.3.6.1.5.5.7.6.37", // id_MLDSA44_RSA2048_PSS_SHA256 "1.3.6.1.5.5.7.6.38", // id_MLDSA44_RSA2048_PKCS15_SHA256 @@ -245,6 +235,43 @@ private void check_ECDSA_Composite(String firstAlg, CompositePublicKey compPub, TestCase.assertEquals("EC", compPriv.getPrivateKeys().get(1).getAlgorithm()); } + public void testKeyBuilders() + throws Exception + { + String[] algorithms = new String[]{ + "MLDSA44-RSA2048-PSS-SHA256", + "MLDSA44-RSA2048-PKCS15-SHA256", + "MLDSA44-Ed25519-SHA512", + "MLDSA44-ECDSA-P256-SHA256", + "MLDSA65-RSA3072-PSS-SHA512", + "MLDSA65-RSA3072-PKCS15-SHA512", + "MLDSA65-RSA4096-PSS-SHA512", + "MLDSA65-RSA4096-PKCS15-SHA512", + "MLDSA65-ECDSA-P256-SHA512", + "MLDSA65-ECDSA-P384-SHA512", + "MLDSA65-ECDSA-brainpoolP256r1-SHA512", + "MLDSA65-Ed25519-SHA512", + "MLDSA87-ECDSA-P384-SHA512", + "MLDSA87-ECDSA-brainpoolP384R1-SHA512", + "MLDSA87-Ed448-SHAKE256", + "MLDSA87-RSA4096-PSS-SHA512", + "MLDSA87-ECDSA-P521-SHA512", + "MLDSA87-RSA3072-PSS-SHA512" + }; + + CompositePublicKey.Builder pubBuilder = null; + CompositePrivateKey.Builder privBuilder = null; + + for (int i = 0; i != algorithms.length; i++) + { + pubBuilder = CompositePublicKey.builder(algorithms[i]); + privBuilder = CompositePrivateKey.builder(algorithms[i]); + } + + assertNotNull(pubBuilder); + assertNotNull(privBuilder); + } + public void testSelfComposition() throws Exception { diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java index 7150056c3c..30ef07cee0 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/CertPathValidatorTest.java @@ -1791,7 +1791,7 @@ private DodgyTBSCertificate( else { seqStart = -1; // field 0 is missing! - version = new ASN1Integer(0); + version = ASN1Integer.ZERO; } boolean isV1 = false; diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java index 4701e449d1..89b3ee3ace 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java @@ -274,7 +274,7 @@ private void testNullParameters() throws Exception { KeyFactory f = KeyFactory.getInstance("DSA", "BC"); - X509EncodedKeySpec x509s = new X509EncodedKeySpec(new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(10001)).getEncoded()); + X509EncodedKeySpec x509s = new X509EncodedKeySpec(new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), ASN1Integer.valueOf(10001)).getEncoded()); DSAPublicKey key1 = (DSAPublicKey)f.generatePublic(x509s); DSAPublicKey key2 = (DSAPublicKey)f.generatePublic(x509s); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java index 6069675087..45ddcd75a0 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/EdECTest.java @@ -751,7 +751,7 @@ private void testPKCS8Override() PrivateKeyInfo info = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded()); isTrue(info.getPublicKeyData() == null); - isTrue(info.getVersion().equals(new ASN1Integer(0))); + isTrue(info.getVersion().equals(ASN1Integer.ZERO)); kpGen = KeyPairGenerator.getInstance("XDH", "BC"); @@ -762,7 +762,7 @@ private void testPKCS8Override() info = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded()); isTrue(info.getPublicKeyData() == null); - isTrue(info.getVersion().equals(new ASN1Integer(0))); + isTrue(info.getVersion().equals(ASN1Integer.ZERO)); System.setProperty("org.bouncycastle.pkcs8.v1_info_only", "false"); @@ -775,7 +775,7 @@ private void testPKCS8Override() info = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded()); isTrue(info.getPublicKeyData() != null); - isTrue(info.getVersion().equals(new ASN1Integer(1))); + isTrue(info.getVersion().equals(ASN1Integer.ONE)); kpGen = KeyPairGenerator.getInstance("XDH", "BC"); @@ -786,7 +786,7 @@ private void testPKCS8Override() info = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded()); isTrue(info.getPublicKeyData() != null); - isTrue(info.getVersion().equals(new ASN1Integer(1))); + isTrue(info.getVersion().equals(ASN1Integer.ONE)); } public static void main( diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/RegressionTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/RegressionTest.java index 9aab17bfc6..9d1038b76b 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/RegressionTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/RegressionTest.java @@ -90,6 +90,7 @@ public class RegressionTest new SkeinTest(), new SlotTwoTest(), new SM2CipherTest(), + new SM2KeyExchangeTest(), new SM2SignatureTest(), new SM4Test(), new ThreefishTest(), diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/SM2KeyExchangeTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/SM2KeyExchangeTest.java new file mode 100644 index 0000000000..80ae3599e2 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/SM2KeyExchangeTest.java @@ -0,0 +1,66 @@ +package org.bouncycastle.jce.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; + +import javax.crypto.KeyAgreement; + +import org.bouncycastle.jcajce.spec.SM2KeyExchangeSpec; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.test.SimpleTest; + +public class SM2KeyExchangeTest + extends SimpleTest +{ + @Override + public String getName() + { + return "SM2KeyExchange"; + } + + @Override + public void performTest() + throws Exception + { + KeyAgreement keyAgreement = KeyAgreement.getInstance("SM2", "BC"); + KeyPairGenerator kpGen = KeyPairGenerator.getInstance("SM2", "BC"); + KeyPair kp1 = kpGen.generateKeyPair(); + KeyPair kp2 = kpGen.generateKeyPair(); + KeyPair kp3 = kpGen.generateKeyPair(); + KeyPair kp4 = kpGen.generateKeyPair(); + + keyAgreement.init(kp1.getPrivate(), new SM2KeyExchangeSpec(true, kp2.getPrivate(), kp4.getPublic(), Strings.toByteArray("ALICE123@YAHOO.COM"), Strings.toByteArray("BILL456@YAHOO.COM"))); + keyAgreement.doPhase(kp3.getPublic(), true); + + byte[] sec1 = keyAgreement.generateSecret(); + + keyAgreement.init(kp3.getPrivate(), new SM2KeyExchangeSpec(false, kp4.getPrivate(), kp2.getPublic(), Strings.toByteArray("BILL456@YAHOO.COM"), Strings.toByteArray("ALICE123@YAHOO.COM"))); + + keyAgreement.doPhase(kp1.getPublic(), true); + + byte[] sec2 = keyAgreement.generateSecret(); + + isTrue(areEqual(sec1, sec2)); + byte[] id1 = new byte[16]; + byte[] id2 = new byte[16]; + SecureRandom random = new SecureRandom(); + random.nextBytes(id1); + random.nextBytes(id2); + + keyAgreement.init(kp1.getPrivate(), new SM2KeyExchangeSpec(true, kp2.getPrivate(), kp4.getPublic(), id1, id2)); + keyAgreement.doPhase(kp3.getPublic(), true); + + byte[] sec3 = keyAgreement.generateSecret(); + + keyAgreement.init(kp3.getPrivate(), new SM2KeyExchangeSpec(false, kp4.getPrivate(), kp2.getPublic(), id2, id1)); + + keyAgreement.doPhase(kp1.getPublic(), true); + + byte[] sec4 = keyAgreement.generateSecret(); + + isTrue(areEqual(sec3, sec4)); + isTrue(!areEqual(sec1, sec4)); + + } +} diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/SM4Test.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/SM4Test.java index 428a9cfe32..b0fe05a489 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/SM4Test.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/SM4Test.java @@ -134,6 +134,10 @@ public void test( public void performTest() throws Exception { + wrapTest(1, "SM4WRAP", Hex.decode("0123456789abcdeffedcba9876543210"), null, + null, Hex.decode("0123456789abcdeffedcba9876543210"), Hex.decode("5d9c31d2f37a186c13943c7e650fbcf895a91f670b7b92bd")); + wrapTest(2, "SM4WRAPPAD", Hex.decode("0123456789abcdeffedcba9876543210"), null, + null, Hex.decode("0123456789abcdeffedcba9876543210"), Hex.decode("7d7110bfbdad2f7b453499338fd40f27014be97c0c69867a")); for (int i = 0; i != cipherTests.length; i += 4) { test(Integer.parseInt(cipherTests[i]), diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/SignedData.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/SignedData.java index ccb897ee69..3fc68af98b 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/SignedData.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/SignedData.java @@ -60,11 +60,6 @@ class SignedData extends ASN1Object { - private static final ASN1Integer VERSION_1 = new ASN1Integer(1); - private static final ASN1Integer VERSION_3 = new ASN1Integer(3); - private static final ASN1Integer VERSION_4 = new ASN1Integer(4); - private static final ASN1Integer VERSION_5 = new ASN1Integer(5); - private ASN1Integer version; private ASN1Set digestAlgorithms; private ContentInfo contentInfo; @@ -159,7 +154,7 @@ else if (tagged.getTagNo() == 3) if (otherCert) { - return new ASN1Integer(5); + return ASN1Integer.FIVE; } if (crls != null) // no need to check if otherCert is true @@ -176,30 +171,30 @@ else if (tagged.getTagNo() == 3) if (otherCrl) { - return VERSION_5; + return ASN1Integer.FIVE; } if (attrCertV2Found) { - return VERSION_4; + return ASN1Integer.FOUR; } if (attrCertV1Found) { - return VERSION_3; + return ASN1Integer.THREE; } if (checkForVersion3(signerInfs)) { - return VERSION_3; + return ASN1Integer.THREE; } if (!CMSObjectIdentifiers.data.equals(contentOid)) { - return VERSION_3; + return ASN1Integer.THREE; } - return VERSION_1; + return ASN1Integer.ONE; } private boolean checkForVersion3(ASN1Set signerInfs) diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/TestCertificateGen.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestCertificateGen.java index e95599ca3f..ba2f0408a8 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/TestCertificateGen.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestCertificateGen.java @@ -57,7 +57,7 @@ public class TestCertificateGen algIds.put("Ed448", new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448)); } - private synchronized static long getSerialNumber() + private static synchronized long getSerialNumber() { return serialNumber++; } @@ -75,7 +75,7 @@ public static X509Certificate createSelfSignedCert(X500Name dn, String sigName, long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(getSerialNumber())); + certGen.setSerialNumber(ASN1Integer.valueOf(getSerialNumber())); certGen.setIssuer(dn); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); @@ -113,7 +113,7 @@ public static X509Certificate createCert(X500Name signerName, PrivateKey signerK long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(getSerialNumber())); + certGen.setSerialNumber(ASN1Integer.valueOf(getSerialNumber())); certGen.setIssuer(signerName); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); @@ -146,7 +146,7 @@ public static X509Certificate createCertWithIDs(X500Name signerName, String sigN long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(getSerialNumber())); + certGen.setSerialNumber(ASN1Integer.valueOf(getSerialNumber())); certGen.setIssuer(signerName); certGen.setSubject(signerName); certGen.setStartDate(new Time(new Date(time - 5000))); diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java index 60c189a742..1c99d038ad 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/TestUtils.java @@ -93,7 +93,7 @@ public static X509Certificate createSelfSignedCert(X500Name dn, String sigName, long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setSerialNumber(ASN1Integer.valueOf(serialNumber.getAndIncrement())); certGen.setIssuer(dn); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); @@ -125,7 +125,7 @@ public static X509Certificate createNoSigCert(X500Name dn, KeyPair keyPair) long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setSerialNumber(ASN1Integer.valueOf(serialNumber.getAndIncrement())); certGen.setIssuer(dn); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); @@ -157,7 +157,7 @@ public static X509Certificate createCert(X500Name signerName, PrivateKey signerK long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setSerialNumber(ASN1Integer.valueOf(serialNumber.getAndIncrement())); certGen.setIssuer(signerName); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/HQCTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/HQCTest.java index 3451ba96eb..e7caacb8c4 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/HQCTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/HQCTest.java @@ -11,21 +11,18 @@ import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import junit.framework.TestCase; import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; import org.bouncycastle.jcajce.spec.KEMExtractSpec; import org.bouncycastle.jcajce.spec.KEMGenerateSpec; import org.bouncycastle.jcajce.spec.KEMParameterSpec; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.pqc.crypto.hqc.HQCKeyGenerationParameters; -import org.bouncycastle.pqc.crypto.hqc.HQCKeyPairGenerator; -import org.bouncycastle.pqc.crypto.hqc.HQCParameters; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.FixedSecureRandom; +import junit.framework.TestCase; + /** * KEM tests for HQC with the BCPQC provider. */ diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java index fc23c7bda4..0e8d20327f 100644 --- a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/KeyStoreTest.java @@ -201,7 +201,7 @@ private static X509Certificate createPQSelfSignedCert(X500Name dn, String sigNam { V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setSerialNumber(ASN1Integer.valueOf(serialNumber.getAndIncrement())); certGen.setIssuer(dn); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); @@ -238,7 +238,7 @@ private static X509Certificate createCert(X500Name signerName, PrivateKey signer long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setSerialNumber(ASN1Integer.valueOf(serialNumber.getAndIncrement())); certGen.setIssuer(signerName); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUPlusKeyPairGeneratorTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUPlusKeyPairGeneratorTest.java new file mode 100644 index 0000000000..4b9d768cd0 --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUPlusKeyPairGeneratorTest.java @@ -0,0 +1,47 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + +import java.security.KeyFactory; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; + +import org.bouncycastle.asn1.bc.BCObjectIdentifiers; +import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec; + +public class NTRUPlusKeyPairGeneratorTest + extends KeyPairGeneratorTest +{ + + protected void setUp() + { + super.setUp(); + } + + public void testKeyFactory() + throws Exception + { + kf = KeyFactory.getInstance("NTRUPLUS", "BCPQC"); + kf = KeyFactory.getInstance(BCObjectIdentifiers.pqc_kem_hqc.getId(), "BCPQC"); + } + + public void testKeyPairEncoding() + throws Exception + { + NTRUPlusParameterSpec[] specs = + new NTRUPlusParameterSpec[] + { + NTRUPlusParameterSpec.ntruplus_768, + NTRUPlusParameterSpec.ntruplus_864, + NTRUPlusParameterSpec.ntruplus_1152 + }; + kf = KeyFactory.getInstance("NTRUPLUS", "BCPQC"); + + kpg = KeyPairGenerator.getInstance("NTRUPLUS", "BCPQC"); + + for (int i = 0; i != specs.length; i++) + { + kpg.initialize(specs[i], new SecureRandom()); + performKeyPairEncodingTest(kpg.generateKeyPair()); + } + } + +} diff --git a/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUPlusTest.java b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUPlusTest.java new file mode 100644 index 0000000000..1c3c27e9ed --- /dev/null +++ b/prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/NTRUPlusTest.java @@ -0,0 +1,160 @@ +package org.bouncycastle.pqc.jcajce.provider.test; + +import java.security.Key; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.Security; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import junit.framework.TestCase; +import org.bouncycastle.jcajce.SecretKeyWithEncapsulation; +import org.bouncycastle.jcajce.spec.KEMExtractSpec; +import org.bouncycastle.jcajce.spec.KEMGenerateSpec; +import org.bouncycastle.jcajce.spec.KEMParameterSpec; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.encoders.Hex; + +public class NTRUPlusTest + extends TestCase +{ + + public void setUp() + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + } + + public void testBasicKEMAES() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRUPLUS", "BCPQC"); + kpg.initialize(NTRUPlusParameterSpec.ntruplus_768, new SecureRandom()); + + performKEMScipher(kpg.generateKeyPair(), "NTRUPLUS", new KEMParameterSpec("AES")); + performKEMScipher(kpg.generateKeyPair(), "NTRUPLUS", new KEMParameterSpec("AES-KWP")); + + kpg.initialize(NTRUPlusParameterSpec.ntruplus_864, new SecureRandom()); + KeyPair hqcKp = kpg.generateKeyPair(); + performKEMScipher(hqcKp, "NTRUPLUS", new KEMParameterSpec("AES")); + performKEMScipher(hqcKp, "NTRUPLUS", new KEMParameterSpec("AES-KWP")); + } + + public void testBasicKEMCamellia() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRUPLUS", "BCPQC"); + kpg.initialize(NTRUPlusParameterSpec.ntruplus_768, new SecureRandom()); + + performKEMScipher(kpg.generateKeyPair(), "NTRUPLUS", new KEMParameterSpec("Camellia")); + performKEMScipher(kpg.generateKeyPair(), "NTRUPLUS", new KEMParameterSpec("Camellia-KWP")); + } + + public void testBasicKEMSEED() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRUPLUS", "BCPQC"); + kpg.initialize(NTRUPlusParameterSpec.ntruplus_768, new SecureRandom()); + + performKEMScipher(kpg.generateKeyPair(), "NTRUPLUS", new KEMParameterSpec("SEED")); + } + + public void testBasicKEMARIA() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRUPLUS", "BCPQC"); + kpg.initialize(NTRUPlusParameterSpec.ntruplus_768, new SecureRandom()); + + performKEMScipher(kpg.generateKeyPair(), "NTRUPLUS", new KEMParameterSpec("ARIA")); + performKEMScipher(kpg.generateKeyPair(), "NTRUPLUS", new KEMParameterSpec("ARIA-KWP")); + } + + private void performKEMScipher(KeyPair kp, String algorithm, KEMParameterSpec ktsParameterSpec) + throws Exception + { + Cipher w1 = Cipher.getInstance(algorithm, "BCPQC"); + + byte[] keyBytes; + if (algorithm.endsWith("KWP")) + { + keyBytes = Hex.decode("000102030405060708090a0b0c0d0e0faa"); + } + else + { + keyBytes = Hex.decode("000102030405060708090a0b0c0d0e0f"); + } + SecretKey key = new SecretKeySpec(keyBytes, "AES"); + + w1.init(Cipher.WRAP_MODE, kp.getPublic(), ktsParameterSpec); + + byte[] data = w1.wrap(key); + + Cipher w2 = Cipher.getInstance(algorithm, "BCPQC"); + + w2.init(Cipher.UNWRAP_MODE, kp.getPrivate(), ktsParameterSpec); + + Key k = w2.unwrap(data, "AES", Cipher.SECRET_KEY); + + assertTrue(Arrays.areEqual(keyBytes, k.getEncoded())); + } + + public void testGenerateAES() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRUPLUS", "BCPQC"); + kpg.initialize(NTRUPlusParameterSpec.ntruplus_768, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyGenerator keyGen = KeyGenerator.getInstance("NTRUPLUS", "BCPQC"); + + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES"), new SecureRandom()); + + SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc1.getAlgorithm()); + assertEquals(32, secEnc1.getEncoded().length); + + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES")); + + SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc2.getAlgorithm()); + + assertTrue(Arrays.areEqual(secEnc1.getEncoded(), secEnc2.getEncoded())); + } + + public void testGenerateAES256() + throws Exception + { + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRUPLUS", "BCPQC"); + kpg.initialize(NTRUPlusParameterSpec.ntruplus_864, new SecureRandom()); + + KeyPair kp = kpg.generateKeyPair(); + + KeyGenerator keyGen = KeyGenerator.getInstance("NTRUPLUS", "BCPQC"); + + keyGen.init(new KEMGenerateSpec(kp.getPublic(), "AES"), new SecureRandom()); + + SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc1.getAlgorithm()); + assertEquals(32, secEnc1.getEncoded().length); + + keyGen.init(new KEMExtractSpec(kp.getPrivate(), secEnc1.getEncapsulation(), "AES")); + + SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation)keyGen.generateKey(); + + assertEquals("AES", secEnc2.getAlgorithm()); + + assertTrue(Arrays.areEqual(secEnc1.getEncoded(), secEnc2.getEncoded())); + } +} diff --git a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/AllTests17.java b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/AllTests17.java similarity index 93% rename from prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/AllTests17.java rename to prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/AllTests17.java index 57642a5fd9..00ff4869bf 100644 --- a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/AllTests17.java +++ b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/AllTests17.java @@ -1,4 +1,4 @@ -package org.bouncycastle.jcacje.provider.test; +package org.bouncycastle.jcajce.provider.test; import junit.framework.Test; import junit.framework.TestCase; diff --git a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/HQCTest.java b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/HQCTest.java similarity index 94% rename from prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/HQCTest.java rename to prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/HQCTest.java index 42f9cefda3..563464619e 100644 --- a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/HQCTest.java +++ b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/HQCTest.java @@ -1,4 +1,4 @@ -package org.bouncycastle.jcacje.provider.test; +package org.bouncycastle.jcajce.provider.test; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -53,7 +53,7 @@ public void testKEM() PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("HQC"); + KEM kemS = KEM.getInstance("HQC", "BCPQC"); KTSParameterSpec ktsSpec = null; KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsSpec, null); KEM.Encapsulated enc = e.encapsulate(); @@ -62,7 +62,7 @@ public void testKEM() byte[] params = enc.params(); // Receiver side - KEM kemR = KEM.getInstance("HQC"); + KEM kemR = KEM.getInstance("HQC", "BCPQC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); SecretKey secR = d.decapsulate(em); @@ -134,14 +134,14 @@ private void performKEM(KeyPair kp, int from, int to, String algorithm, KTSParam PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("HQC"); + KEM kemS = KEM.getInstance("HQC", "BCPQC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(from, to, algorithm); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("HQC"); + KEM kemR = KEM.getInstance("HQC", "BCPQC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); SecretKey secR = d.decapsulate(em, from, to, algorithm); @@ -156,14 +156,14 @@ private void performKEM(KeyPair kp, KTSParameterSpec ktsParameterSpec) PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("HQC"); + KEM kemS = KEM.getInstance("HQC", "BCPQC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("HQC"); + KEM kemR = KEM.getInstance("HQC", "BCPQC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); SecretKey secR = d.decapsulate(em); diff --git a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/MLKEMTest.java b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/MLKEMTest.java similarity index 93% rename from prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/MLKEMTest.java rename to prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/MLKEMTest.java index d2dfd9d8d8..fad061b140 100644 --- a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/MLKEMTest.java +++ b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/MLKEMTest.java @@ -1,6 +1,14 @@ -package org.bouncycastle.jcacje.provider.test; +package org.bouncycastle.jcajce.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; + +import javax.crypto.KEM; +import javax.crypto.SecretKey; -import junit.framework.TestCase; import org.bouncycastle.jcajce.spec.KEMParameterSpec; import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.jcajce.spec.MLKEMParameterSpec; @@ -8,14 +16,7 @@ import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.util.Arrays; -import javax.crypto.KEM; -import javax.crypto.SecretKey; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.Security; - +import junit.framework.TestCase; public class MLKEMTest extends TestCase @@ -40,7 +41,7 @@ public void testKEM() PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("ML-KEM"); + KEM kemS = KEM.getInstance("ML-KEM", "BC"); KTSParameterSpec ktsSpec = null; KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsSpec, null); KEM.Encapsulated enc = e.encapsulate(); @@ -49,7 +50,7 @@ public void testKEM() byte[] params = enc.params(); // Receiver side - KEM kemR = KEM.getInstance("ML-KEM"); + KEM kemR = KEM.getInstance("ML-KEM", "BC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); SecretKey secR = d.decapsulate(em); @@ -123,14 +124,14 @@ private void performKEM(KeyPair kp, int from, int to, String algorithm, KTSParam PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("ML-KEM"); + KEM kemS = KEM.getInstance("ML-KEM", "BC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(from, to, algorithm); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("ML-KEM"); + KEM kemR = KEM.getInstance("ML-KEM", "BC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); SecretKey secR = d.decapsulate(em, from, to, algorithm); @@ -145,14 +146,14 @@ private void performKEM(KeyPair kp, KTSParameterSpec ktsParameterSpec) PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("ML-KEM"); + KEM kemS = KEM.getInstance("ML-KEM", "BC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("ML-KEM"); + KEM kemR = KEM.getInstance("ML-KEM", "BC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); SecretKey secR = d.decapsulate(em); diff --git a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/NTRUKEMTest.java b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/NTRUKEMTest.java similarity index 98% rename from prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/NTRUKEMTest.java rename to prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/NTRUKEMTest.java index 0b95b45d07..8d50bf9c68 100644 --- a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/NTRUKEMTest.java +++ b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/NTRUKEMTest.java @@ -1,4 +1,4 @@ -package org.bouncycastle.jcacje.provider.test; +package org.bouncycastle.jcajce.provider.test; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -9,15 +9,15 @@ import javax.crypto.KEM; import javax.crypto.SecretKey; -import junit.framework.TestCase; import org.bouncycastle.jcajce.spec.KEMParameterSpec; import org.bouncycastle.jcajce.spec.KTSParameterSpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec; -import org.bouncycastle.pqc.jcajce.interfaces.NTRUKey; import org.bouncycastle.util.Arrays; +import junit.framework.TestCase; + public class NTRUKEMTest extends TestCase @@ -47,13 +47,13 @@ public void setUp() // FixedSecureRandom fixedRandom = new FixedSecureRandom(fixedRandomBytes); // // // Receiver side -// KeyPairGenerator g = KeyPairGenerator.getInstance("NTRU"); +// KeyPairGenerator g = KeyPairGenerator.getInstance("NTRU", "BCPQC"); // g.initialize(NTRUParameterSpec.sntrup653, fixedRandom); // KeyPair kp = g.generateKeyPair(); // NTRUKey pkR = (NTRUKey)kp.getPublic(); // // // Sender side -// KEM kemS = KEM.getInstance("NTRU"); +// KEM kemS = KEM.getInstance("NTRU", "BCPQC"); // KTSParameterSpec ktsSpec = null; // KEM.Encapsulator e = kemS.newEncapsulator((PublicKey)pkR, ktsSpec, fixedRandom); // KEM.Encapsulated enc = e.encapsulate(); @@ -65,7 +65,7 @@ public void setUp() // assertTrue(Arrays.areEqual(enc.key().getEncoded(), ss)); // // // Receiver side -// KEM kemR = KEM.getInstance("NTRU"); +// KEM kemR = KEM.getInstance("NTRU", "BCPQC"); // KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); // SecretKey secR = d.decapsulate(em); // @@ -86,7 +86,7 @@ public void testKEM() PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("NTRU"); + KEM kemS = KEM.getInstance("NTRU", "BCPQC"); KTSParameterSpec ktsSpec = null; KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsSpec, null); KEM.Encapsulated enc = e.encapsulate(); @@ -95,8 +95,8 @@ public void testKEM() byte[] params = enc.params(); // Receiver side - KEM kemR = KEM.getInstance("NTRU"); -// AlgorithmParameters algParams = AlgorithmParameters.getInstance("NTRU"); + KEM kemR = KEM.getInstance("NTRU", "BCPQC"); +// AlgorithmParameters algParams = AlgorithmParameters.getInstance("NTRU", "BCPQC"); // algParams.init(params); // NTRUParameterSpec specR = algParams.getParameterSpec(NTRUParameterSpec.class); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); @@ -114,7 +114,7 @@ public void testBasicKEMAES() { Security.addProvider(new BouncyCastlePQCProvider()); } - KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BC"); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("NTRU", "BCPQC"); kpg.initialize(NTRUParameterSpec.ntruhps2048509, new SecureRandom()); performKEM(kpg.generateKeyPair(), new KEMParameterSpec("AES")); @@ -172,14 +172,14 @@ private void performKEM(KeyPair kp, int from, int to, String algorithm, KTSParam PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("NTRU"); + KEM kemS = KEM.getInstance("NTRU", "BCPQC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(from, to, algorithm); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("NTRU"); + KEM kemR = KEM.getInstance("NTRU", "BCPQC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); SecretKey secR = d.decapsulate(em, from, to, algorithm); @@ -194,14 +194,14 @@ private void performKEM(KeyPair kp, KTSParameterSpec ktsParameterSpec) PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("NTRU"); + KEM kemS = KEM.getInstance("NTRU", "BCPQC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("NTRU"); + KEM kemR = KEM.getInstance("NTRU", "BCPQC"); // KTSParameterSpec RktsParameterSpec = new KTSParameterSpec.Builder( // ktsParameterSpec.getKeyAlgorithmName(), // enc.key().getEncoded().length diff --git a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/SNTRUPrimeKEMTest.java b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/SNTRUPrimeKEMTest.java similarity index 97% rename from prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/SNTRUPrimeKEMTest.java rename to prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/SNTRUPrimeKEMTest.java index e20c3838dd..03fea2cadd 100644 --- a/prov/src/test/jdk17/org/bouncycastle/jcacje/provider/test/SNTRUPrimeKEMTest.java +++ b/prov/src/test/jdk17/org/bouncycastle/jcajce/provider/test/SNTRUPrimeKEMTest.java @@ -1,4 +1,4 @@ -package org.bouncycastle.jcacje.provider.test; +package org.bouncycastle.jcajce.provider.test; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -48,13 +48,13 @@ public void testKEMVec() FixedSecureRandom fixedRandom = new FixedSecureRandom(fixedRandomBytes); // Receiver side - KeyPairGenerator g = KeyPairGenerator.getInstance("SNTRUPrime"); + KeyPairGenerator g = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); g.initialize(SNTRUPrimeParameterSpec.sntrup653, fixedRandom); KeyPair kp = g.generateKeyPair(); SNTRUPrimeKey pkR = (SNTRUPrimeKey)kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("SNTRUPrime"); //Should the name be "SNTRUPrime-KEM" ? + KEM kemS = KEM.getInstance("SNTRUPrime", "BCPQC"); //Should the name be "SNTRUPrime-KEM" ? KTSParameterSpec ktsSpec = null; KEM.Encapsulator e = kemS.newEncapsulator((PublicKey)pkR, ktsSpec, fixedRandom); KEM.Encapsulated enc = e.encapsulate(); @@ -66,7 +66,7 @@ public void testKEMVec() assertTrue(Arrays.areEqual(enc.key().getEncoded(), ss)); // Receiver side - KEM kemR = KEM.getInstance("SNTRUPrime"); + KEM kemR = KEM.getInstance("SNTRUPrime", "BCPQC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); SecretKey secR = d.decapsulate(em); @@ -79,7 +79,7 @@ public void testKEM() throws Exception { // Receiver side - KeyPairGenerator g = KeyPairGenerator.getInstance("SNTRUPrime"); + KeyPairGenerator g = KeyPairGenerator.getInstance("SNTRUPrime", "BCPQC"); g.initialize(SNTRUPrimeParameterSpec.sntrup653, new SecureRandom()); @@ -87,7 +87,7 @@ public void testKEM() PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("SNTRUPrime"); //Should the name be "SNTRUPrime-KEM" ? + KEM kemS = KEM.getInstance("SNTRUPrime", "BCPQC"); //Should the name be "SNTRUPrime-KEM" ? KTSParameterSpec ktsSpec = null; KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsSpec, null); KEM.Encapsulated enc = e.encapsulate(); @@ -96,8 +96,8 @@ public void testKEM() byte[] params = enc.params(); // Receiver side - KEM kemR = KEM.getInstance("SNTRUPrime"); -// AlgorithmParameters algParams = AlgorithmParameters.getInstance("SNTRUPrime"); + KEM kemR = KEM.getInstance("SNTRUPrime", "BCPQC"); +// AlgorithmParameters algParams = AlgorithmParameters.getInstance("SNTRUPrime", "BCPQC"); // algParams.init(params); // SNTRUPrimeParameterSpec specR = algParams.getParameterSpec(SNTRUPrimeParameterSpec.class); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsSpec); @@ -173,14 +173,14 @@ private void performKEM(KeyPair kp, int from, int to, String algorithm, KTSParam PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("SNTRUPrime"); + KEM kemS = KEM.getInstance("SNTRUPrime", "BCPQC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(from, to, algorithm); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("SNTRUPrime"); + KEM kemR = KEM.getInstance("SNTRUPrime", "BCPQC"); KEM.Decapsulator d = kemR.newDecapsulator(kp.getPrivate(), ktsParameterSpec); SecretKey secR = d.decapsulate(em, from, to, algorithm); @@ -195,14 +195,14 @@ private void performKEM(KeyPair kp, KTSParameterSpec ktsParameterSpec) PublicKey pkR = kp.getPublic(); // Sender side - KEM kemS = KEM.getInstance("SNTRUPrime"); + KEM kemS = KEM.getInstance("SNTRUPrime", "BCPQC"); KEM.Encapsulator e = kemS.newEncapsulator(pkR, ktsParameterSpec, null); KEM.Encapsulated enc = e.encapsulate(); SecretKey secS = enc.key(); byte[] em = enc.encapsulation(); // Receiver side - KEM kemR = KEM.getInstance("SNTRUPrime"); + KEM kemR = KEM.getInstance("SNTRUPrime", "BCPQC"); // KTSParameterSpec RktsParameterSpec = new KTSParameterSpec.Builder( // ktsParameterSpec.getKeyAlgorithmName(), // enc.key().getEncoded().length diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java b/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java index b785e38ecf..6c89fc5b20 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/BouncyCastleJsseProvider.java @@ -362,7 +362,7 @@ public final Provider.Service getService(String type, String algorithm) return service; } - public synchronized final Set getServices() + public final synchronized Set getServices() { Set serviceSet = super.getServices(); Set bcServiceSet = new HashSet(); diff --git a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java index 19dcf101db..3fc9d4bf24 100644 --- a/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java +++ b/tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLContextSpi.java @@ -342,9 +342,11 @@ private static Map createSupportedProtocolMapFips( } private static String[] getDefaultEnabledCipherSuites(Map supportedCipherSuiteMap, - List defaultCipherSuiteList, boolean disableDHDefaultSuites, String cipherSuitesPropertyName) + List defaultCipherSuiteList, boolean disableDHDefaultSuites, String cipherSuitesPropertyName, + String title) { List candidates = getJdkTlsCipherSuites(cipherSuitesPropertyName, defaultCipherSuiteList); + boolean disableDHSuites = disableDHDefaultSuites && candidates == defaultCipherSuiteList; String[] result = new String[candidates.size()]; int count = 0; @@ -355,15 +357,15 @@ private static String[] getDefaultEnabledCipherSuites(Map supportedCipherSuiteMap, @@ -389,7 +391,7 @@ private static String[] getDefaultEnabledCipherSuitesServer(Map supportedProtocolMap, diff --git a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsContext.java b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsContext.java index 401579b2c2..7f19fa9875 100644 --- a/tls/src/main/java/org/bouncycastle/tls/AbstractTlsContext.java +++ b/tls/src/main/java/org/bouncycastle/tls/AbstractTlsContext.java @@ -16,7 +16,7 @@ abstract class AbstractTlsContext { private static long counter = Times.nanoTime(); - private synchronized static long nextCounterValue() + private static synchronized long nextCounterValue() { return ++counter; } diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/RSAUtil.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/RSAUtil.java index c84d1ebe46..94522f666d 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/RSAUtil.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/RSAUtil.java @@ -43,9 +43,9 @@ public class RSAUtil AlgorithmIdentifier mgf1SHA384Identifier_B = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, sha384Identifier_B); AlgorithmIdentifier mgf1SHA512Identifier_B = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, sha512Identifier_B); - ASN1Integer sha256Size = new ASN1Integer(TlsCryptoUtils.getHashOutputSize(CryptoHashAlgorithm.sha256)); - ASN1Integer sha384Size = new ASN1Integer(TlsCryptoUtils.getHashOutputSize(CryptoHashAlgorithm.sha384)); - ASN1Integer sha512Size = new ASN1Integer(TlsCryptoUtils.getHashOutputSize(CryptoHashAlgorithm.sha512)); + ASN1Integer sha256Size = ASN1Integer.valueOf(TlsCryptoUtils.getHashOutputSize(CryptoHashAlgorithm.sha256)); + ASN1Integer sha384Size = ASN1Integer.valueOf(TlsCryptoUtils.getHashOutputSize(CryptoHashAlgorithm.sha384)); + ASN1Integer sha512Size = ASN1Integer.valueOf(TlsCryptoUtils.getHashOutputSize(CryptoHashAlgorithm.sha512)); ASN1Integer trailerField = RSASSAPSSparams.DEFAULT_TRAILER_FIELD; diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java index ad6ee2ced9..d6fb48e227 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java @@ -458,7 +458,7 @@ public AlgorithmParameters getNamedGroupAlgorithmParameters(int namedGroup) */ return null; } - else if (NamedGroup.refersToAnECDSACurve(namedGroup)) + else if (NamedGroup.refersToASpecificCurve(namedGroup)) { return ECUtil.getAlgorithmParameters(this, NamedGroup.getCurveName(namedGroup)); } @@ -1238,11 +1238,7 @@ protected Boolean isSupportedNamedGroup(int namedGroup) } } } - else if (NamedGroup.refersToASpecificKem(namedGroup)) - { - return Boolean.valueOf(KemUtil.isKemSupported(this, NamedGroup.getKemName(namedGroup))); - } - else if (NamedGroup.refersToAnECDSACurve(namedGroup)) + else if (NamedGroup.refersToASpecificCurve(namedGroup)) { return Boolean.valueOf(ECUtil.isCurveSupported(this, NamedGroup.getCurveName(namedGroup))); } @@ -1250,6 +1246,10 @@ else if (NamedGroup.refersToASpecificFiniteField(namedGroup)) { return Boolean.valueOf(DHUtil.isGroupSupported(this, TlsDHUtils.getNamedDHGroup(namedGroup))); } + else if (NamedGroup.refersToASpecificKem(namedGroup)) + { + return Boolean.valueOf(KemUtil.isKemSupported(this, NamedGroup.getKemName(namedGroup))); + } } catch (GeneralSecurityException e) { diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKem.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKem.java index 325eaf82a1..330280d125 100644 --- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKem.java +++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JceTlsMLKem.java @@ -35,7 +35,7 @@ public byte[] generateEphemeral() throws IOException { KeyPair kp = domain.generateKeyPair(); this.privateKey = kp.getPrivate(); - return KemUtil.encodePublicKey(kp.getPublic()); + return domain.encodePublicKey(kp.getPublic()); } } diff --git a/tls/src/main/jdk1.5/org/bouncycastle/tls/crypto/impl/jcajce/SecretKeyUtil.java b/tls/src/main/jdk1.5/org/bouncycastle/tls/crypto/impl/jcajce/SecretKeyUtil.java new file mode 100644 index 0000000000..b8f3573387 --- /dev/null +++ b/tls/src/main/jdk1.5/org/bouncycastle/tls/crypto/impl/jcajce/SecretKeyUtil.java @@ -0,0 +1,21 @@ +package org.bouncycastle.tls.crypto.impl.jcajce; + +import javax.crypto.SecretKey; +import javax.security.auth.Destroyable; + +abstract class SecretKeyUtil +{ + static void destroy(SecretKey secretKey) + { + if (secretKey instanceof Destroyable) + { + try + { + ((Destroyable)secretKey).destroy(); + } + catch (Exception e) + { + } + } + } +} diff --git a/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/SecretKeyUtil.java b/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/SecretKeyUtil.java new file mode 100644 index 0000000000..e335edc6be --- /dev/null +++ b/tls/src/main/jdk1.9/org/bouncycastle/tls/crypto/impl/jcajce/SecretKeyUtil.java @@ -0,0 +1,21 @@ +package org.bouncycastle.tls.crypto.impl.jcajce; + +import javax.crypto.SecretKey; +import javax.security.auth.Destroyable; + +abstract class SecretKeyUtil +{ + static void destroy(SecretKey secretKey) + { + if (secretKey != null) + { + try + { + ((Destroyable)secretKey).destroy(); + } + catch (Exception e) + { + } + } + } +} diff --git a/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java b/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java index 1a8facb158..4d2d65a312 100644 --- a/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java +++ b/tls/src/test/java/org/bouncycastle/jsse/provider/test/TestUtils.java @@ -107,7 +107,7 @@ private static Map createAlgIDs() new RSASSAPSSparams( sha256Identifier, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, sha256Identifier), - new ASN1Integer(sha256OutputSize), + ASN1Integer.valueOf(sha256OutputSize), RSASSAPSSparams.DEFAULT_TRAILER_FIELD))); algIDs.put("SHA1withECDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA1)); algIDs.put("SHA224withECDSA", new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA224)); @@ -204,7 +204,7 @@ public static X509Certificate createSelfSignedCert(X500Name dn, String sigName, long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setSerialNumber(ASN1Integer.valueOf(serialNumber.getAndIncrement())); certGen.setIssuer(dn); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); @@ -244,7 +244,7 @@ public static X509Certificate createCert(X500Name signerName, PrivateKey signerK long time = System.currentTimeMillis(); - certGen.setSerialNumber(new ASN1Integer(serialNumber.getAndIncrement())); + certGen.setSerialNumber(ASN1Integer.valueOf(serialNumber.getAndIncrement())); certGen.setIssuer(signerName); certGen.setSubject(dn); certGen.setStartDate(new Time(new Date(time - 5000))); diff --git a/util/src/main/java/org/bouncycastle/asn1/bsi/BSIObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/bsi/BSIObjectIdentifiers.java index ec27b05e1f..62d510ae6d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/bsi/BSIObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/bsi/BSIObjectIdentifiers.java @@ -11,10 +11,10 @@ public interface BSIObjectIdentifiers /* 0.4.0.127.0.7.1.1 */ static final ASN1ObjectIdentifier id_ecc = bsi_de.branch("1.1"); - + /* 0.4.0.127.0.7.1.1.4.1 */ static final ASN1ObjectIdentifier ecdsa_plain_signatures = id_ecc.branch("4.1"); - + /* 0.4.0.127.0.7.1.1.4.1.1 */ static final ASN1ObjectIdentifier ecdsa_plain_SHA1 = ecdsa_plain_signatures.branch("1"); diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/BodyPartID.java b/util/src/main/java/org/bouncycastle/asn1/cmc/BodyPartID.java index 5d09025677..21977681f7 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/BodyPartID.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/BodyPartID.java @@ -66,6 +66,6 @@ public long getID() public ASN1Primitive toASN1Primitive() { - return new ASN1Integer(id); + return ASN1Integer.valueOf(id); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCFailInfo.java b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCFailInfo.java index b71dd14fa5..205688678a 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCFailInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCFailInfo.java @@ -30,20 +30,20 @@ public class CMCFailInfo extends ASN1Object { - public static final CMCFailInfo badAlg = new CMCFailInfo(new ASN1Integer(0)); - public static final CMCFailInfo badMessageCheck = new CMCFailInfo(new ASN1Integer(1)); - public static final CMCFailInfo badRequest = new CMCFailInfo(new ASN1Integer(2)); - public static final CMCFailInfo badTime = new CMCFailInfo(new ASN1Integer(3)); - public static final CMCFailInfo badCertId = new CMCFailInfo(new ASN1Integer(4)); - public static final CMCFailInfo unsupportedExt = new CMCFailInfo(new ASN1Integer(5)); - public static final CMCFailInfo mustArchiveKeys = new CMCFailInfo(new ASN1Integer(6)); - public static final CMCFailInfo badIdentity = new CMCFailInfo(new ASN1Integer(7)); - public static final CMCFailInfo popRequired = new CMCFailInfo(new ASN1Integer(8)); - public static final CMCFailInfo popFailed = new CMCFailInfo(new ASN1Integer(9)); - public static final CMCFailInfo noKeyReuse = new CMCFailInfo(new ASN1Integer(10)); - public static final CMCFailInfo internalCAError = new CMCFailInfo(new ASN1Integer(11)); - public static final CMCFailInfo tryLater = new CMCFailInfo(new ASN1Integer(12)); - public static final CMCFailInfo authDataFail = new CMCFailInfo(new ASN1Integer(13)); + public static final CMCFailInfo badAlg = new CMCFailInfo(ASN1Integer.valueOf(0)); + public static final CMCFailInfo badMessageCheck = new CMCFailInfo(ASN1Integer.valueOf(1)); + public static final CMCFailInfo badRequest = new CMCFailInfo(ASN1Integer.valueOf(2)); + public static final CMCFailInfo badTime = new CMCFailInfo(ASN1Integer.valueOf(3)); + public static final CMCFailInfo badCertId = new CMCFailInfo(ASN1Integer.valueOf(4)); + public static final CMCFailInfo unsupportedExt = new CMCFailInfo(ASN1Integer.valueOf(5)); + public static final CMCFailInfo mustArchiveKeys = new CMCFailInfo(ASN1Integer.valueOf(6)); + public static final CMCFailInfo badIdentity = new CMCFailInfo(ASN1Integer.valueOf(7)); + public static final CMCFailInfo popRequired = new CMCFailInfo(ASN1Integer.valueOf(8)); + public static final CMCFailInfo popFailed = new CMCFailInfo(ASN1Integer.valueOf(9)); + public static final CMCFailInfo noKeyReuse = new CMCFailInfo(ASN1Integer.valueOf(10)); + public static final CMCFailInfo internalCAError = new CMCFailInfo(ASN1Integer.valueOf(11)); + public static final CMCFailInfo tryLater = new CMCFailInfo(ASN1Integer.valueOf(12)); + public static final CMCFailInfo authDataFail = new CMCFailInfo(ASN1Integer.valueOf(13)); private static Map range = new HashMap(); diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCObjectIdentifiers.java index 40731daf36..90ef2b46ae 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCObjectIdentifiers.java @@ -11,14 +11,14 @@ public interface CMCObjectIdentifiers // id_pkix OBJECT IDENTIFIER ::= { iso(1) identified_organization(3) // dod(6) internet(1) security(5) mechanisms(5) pkix(7) } ASN1ObjectIdentifier id_pkix = new ASN1ObjectIdentifier("1.3.6.1.5.5.7"); - + ASN1ObjectIdentifier id_cmc = id_pkix.branch("7"); // CMC controls ASN1ObjectIdentifier id_cct = id_pkix.branch("12"); // CMC content types ASN1ObjectIdentifier id_kp = id_pkix.branch("3"); // KP // The following controls have the type OCTET STRING - + ASN1ObjectIdentifier id_cmc_identityProof = id_cmc.branch("3"); ASN1ObjectIdentifier id_cmc_dataReturn = id_cmc.branch("4"); ASN1ObjectIdentifier id_cmc_regInfo = id_cmc.branch("18"); @@ -26,22 +26,22 @@ public interface CMCObjectIdentifiers ASN1ObjectIdentifier id_cmc_queryPending = id_cmc.branch("21"); ASN1ObjectIdentifier id_cmc_popLinkRandom = id_cmc.branch("22"); ASN1ObjectIdentifier id_cmc_popLinkWitness = id_cmc.branch("23"); - + // The following controls have the type UTF8String - + ASN1ObjectIdentifier id_cmc_identification = id_cmc.branch("2"); - + // The following controls have the type INTEGER - + ASN1ObjectIdentifier id_cmc_transactionId = id_cmc.branch("5"); - + // The following controls have the type OCTET STRING - + ASN1ObjectIdentifier id_cmc_senderNonce = id_cmc.branch("6"); ASN1ObjectIdentifier id_cmc_recipientNonce = id_cmc.branch("7"); - + // This is the content type used for a request message in the protocol - + ASN1ObjectIdentifier id_cct_PKIData = id_cct.branch("2"); // This defines the response message in the protocol @@ -99,7 +99,7 @@ public interface CMCObjectIdentifiers // Identity Proof control w/ algorithm agility ASN1ObjectIdentifier id_cmc_identityProofV2 = id_cmc.branch("34"); - + ASN1ObjectIdentifier id_cmc_popLinkWitnessV2 = id_cmc.branch("33"); // Extended key usage diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatus.java b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatus.java index 8aa8c85d88..8bef9655cc 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatus.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/CMCStatus.java @@ -24,13 +24,13 @@ public class CMCStatus extends ASN1Object { - public static final CMCStatus success = new CMCStatus(new ASN1Integer(0)); - public static final CMCStatus failed = new CMCStatus(new ASN1Integer(2)); - public static final CMCStatus pending = new CMCStatus(new ASN1Integer(3)); - public static final CMCStatus noSupport = new CMCStatus(new ASN1Integer(4)); - public static final CMCStatus confirmRequired = new CMCStatus(new ASN1Integer(5)); - public static final CMCStatus popRequired = new CMCStatus(new ASN1Integer(6)); - public static final CMCStatus partial = new CMCStatus(new ASN1Integer(7)); + public static final CMCStatus success = new CMCStatus(ASN1Integer.valueOf(0)); + public static final CMCStatus failed = new CMCStatus(ASN1Integer.valueOf(2)); + public static final CMCStatus pending = new CMCStatus(ASN1Integer.valueOf(3)); + public static final CMCStatus noSupport = new CMCStatus(ASN1Integer.valueOf(4)); + public static final CMCStatus confirmRequired = new CMCStatus(ASN1Integer.valueOf(5)); + public static final CMCStatus popRequired = new CMCStatus(ASN1Integer.valueOf(6)); + public static final CMCStatus partial = new CMCStatus(ASN1Integer.valueOf(7)); private static Map range = new HashMap(); diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java b/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java index 5b111ac646..09931b75bf 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/CertificationRequest.java @@ -35,8 +35,6 @@ public class CertificationRequest extends ASN1Object { - private static final ASN1Integer ZERO = new ASN1Integer(0); - private final CertificationRequestInfo certificationRequestInfo; private final AlgorithmIdentifier signatureAlgorithm; private final ASN1BitString signature; @@ -173,9 +171,9 @@ private CertificationRequestInfo( private CertificationRequestInfo(X500Name subject, AlgorithmIdentifier algorithm, ASN1BitString subjectPublicKey, ASN1Set attributes) { - this.version = ZERO; + this.version = ASN1Integer.ZERO; this.subject = subject; - this.subjectPublicKeyInfo = new DERSequence(new ASN1Encodable[] { algorithm, subjectPublicKey }); + this.subjectPublicKeyInfo = new DERSequence(algorithm, subjectPublicKey); this.attributes = attributes; } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/IdentityProofV2.java b/util/src/main/java/org/bouncycastle/asn1/cmc/IdentityProofV2.java index 955d768fa1..0a0c486067 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/IdentityProofV2.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/IdentityProofV2.java @@ -26,14 +26,14 @@ public class IdentityProofV2 private final AlgorithmIdentifier proofAlgID; private final AlgorithmIdentifier macAlgId; private final byte[] witness; - + public IdentityProofV2(AlgorithmIdentifier proofAlgID, AlgorithmIdentifier macAlgId, byte[] witness) { this.proofAlgID = proofAlgID; this.macAlgId = macAlgId; this.witness = Arrays.clone(witness); } - + private IdentityProofV2(ASN1Sequence seq) { if (seq.size() != 3) @@ -59,7 +59,7 @@ public static IdentityProofV2 getInstance(Object o) return null; } - + public AlgorithmIdentifier getProofAlgID() { return proofAlgID; @@ -74,15 +74,15 @@ public byte[] getWitness() { return Arrays.clone(witness); } - + public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(3); - + v.add(proofAlgID); v.add(macAlgId); v.add(new DEROctetString(getWitness())); - + return new DERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmc/OtherStatusInfo.java b/util/src/main/java/org/bouncycastle/asn1/cmc/OtherStatusInfo.java index 46ef16aff9..d596896bc8 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmc/OtherStatusInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmc/OtherStatusInfo.java @@ -61,7 +61,7 @@ else if (obj instanceof byte[]) { throw new IllegalArgumentException("parsing error: " + e.getMessage()); } - } + } throw new IllegalArgumentException("unknown object in getInstance(): " + obj.getClass().getName()); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java index 012f2e06b3..10942312a1 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CMPCertificate.java @@ -7,7 +7,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -97,7 +96,7 @@ public static CMPCertificate getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject taggedObject = ASN1TaggedObject.getContextInstance(o); return new CMPCertificate(taggedObject.getTagNo(), taggedObject.getBaseObject()); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java index 129752dee5..0ad6bd209d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertAnnContent.java @@ -6,7 +6,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -92,7 +91,7 @@ public static CertAnnContent getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject taggedObject = ASN1TaggedObject.getContextInstance(o); return new CertAnnContent(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject()); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java index b660cea49d..39e4b21c69 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertOrEncCert.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1Util; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.EncryptedKey; import org.bouncycastle.asn1.crmf.EncryptedValue; @@ -78,7 +77,7 @@ public static CertOrEncCert getInstance(Object o) if (o instanceof ASN1TaggedObject) { - return new CertOrEncCert(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new CertOrEncCert(ASN1TaggedObject.getContextInstance(o)); } return null; diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java b/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java index f362082e8a..782820c4cc 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/CertifiedKeyPair.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.crmf.EncryptedKey; @@ -37,7 +36,7 @@ private CertifiedKeyPair(ASN1Sequence seq) { if (seq.size() == 2) { - ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1), BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject tagged = ASN1TaggedObject.getContextInstance(seq.getObjectAt(1)); if (tagged.getTagNo() == 0) { privateKey = EncryptedKey.getInstance(tagged.getExplicitBaseObject()); @@ -49,8 +48,8 @@ private CertifiedKeyPair(ASN1Sequence seq) } else { - privateKey = EncryptedKey.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(1), BERTags.CONTEXT_SPECIFIC).getExplicitBaseObject()); - publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(2), BERTags.CONTEXT_SPECIFIC).getExplicitBaseObject()); + privateKey = EncryptedKey.getInstance(ASN1TaggedObject.getContextInstance(seq.getObjectAt(1)).getExplicitBaseObject()); + publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getContextInstance(seq.getObjectAt(2)).getExplicitBaseObject()); } } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/KemBMParameter.java b/util/src/main/java/org/bouncycastle/asn1/cmp/KemBMParameter.java index 3a5705e280..2ca549ecc8 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/KemBMParameter.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/KemBMParameter.java @@ -51,7 +51,7 @@ public KemBMParameter( long len, AlgorithmIdentifier mac) { - this(kdf, new ASN1Integer(len), mac); + this(kdf, ASN1Integer.valueOf(len), mac); } public static KemBMParameter getInstance(Object o) diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/KemOtherInfo.java b/util/src/main/java/org/bouncycastle/asn1/cmp/KemOtherInfo.java index 5140a22ceb..e63e7bb57b 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/KemOtherInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/KemOtherInfo.java @@ -65,7 +65,7 @@ public KemOtherInfo( AlgorithmIdentifier mac, ASN1OctetString ct) { - this(transactionID, senderNonce, recipNonce, new ASN1Integer(len), mac, ct); + this(transactionID, senderNonce, recipNonce, ASN1Integer.valueOf(len), mac, ct); } private KemOtherInfo(ASN1Sequence seq) diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java b/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java index 58870f63c1..76422e3259 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/KeyRecRepContent.java @@ -8,7 +8,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -38,7 +37,7 @@ private KeyRecRepContent(ASN1Sequence seq) while (en.hasMoreElements()) { - ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(en.nextElement(), BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject tObj = ASN1TaggedObject.getContextInstance(en.nextElement()); switch (tObj.getTagNo()) { diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java b/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java index 1963bb2f60..fbab86325e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/OOBCert.java @@ -6,7 +6,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.x509.AttributeCertificate; import org.bouncycastle.asn1.x509.Certificate; @@ -87,7 +86,7 @@ public static OOBCert getInstance(Object o) if (o instanceof ASN1TaggedObject) { - ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject taggedObject = ASN1TaggedObject.getContextInstance(o); return new OOBCert(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject()); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PBMParameter.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PBMParameter.java index 0b72b4bd06..b58550deb9 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PBMParameter.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PBMParameter.java @@ -49,8 +49,7 @@ public PBMParameter( int iterationCount, AlgorithmIdentifier mac) { - this(new DEROctetString(salt), owf, - new ASN1Integer(iterationCount), mac); + this(new DEROctetString(salt), owf, ASN1Integer.valueOf(iterationCount), mac); } public PBMParameter( diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java index d4351c6858..b9568d9eb6 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIBody.java @@ -88,7 +88,7 @@ private PKIBody(ASN1TaggedObject tagged) throw Exceptions.illegalArgumentException("malformed body found: " + e.getMessage(), e); } catch (IllegalArgumentException e) - { + { throw Exceptions.illegalArgumentException("malformed body found: " + e.getMessage(), e); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java index acd06f529c..19f3ca8934 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeader.java @@ -135,7 +135,7 @@ public PKIHeader( GeneralName sender, GeneralName recipient) { - this(new ASN1Integer(pvno), sender, recipient); + this(ASN1Integer.valueOf(pvno), sender, recipient); } private PKIHeader( diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeaderBuilder.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeaderBuilder.java index 53c0d83096..9e3b0e279f 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeaderBuilder.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIHeaderBuilder.java @@ -33,7 +33,7 @@ public PKIHeaderBuilder( GeneralName sender, GeneralName recipient) { - this(new ASN1Integer(pvno), sender, recipient); + this(ASN1Integer.valueOf(pvno), sender, recipient); } private PKIHeaderBuilder( diff --git a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatus.java b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatus.java index 8892020f98..87e3fb53e5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatus.java +++ b/util/src/main/java/org/bouncycastle/asn1/cmp/PKIStatus.java @@ -54,7 +54,7 @@ public class PKIStatus private PKIStatus(int value) { - this(new ASN1Integer(value)); + this(ASN1Integer.valueOf(value)); } private PKIStatus(ASN1Integer value) diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/Attribute.java b/util/src/main/java/org/bouncycastle/asn1/cms/Attribute.java index ff4c42dad7..026862d24a 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/Attribute.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/Attribute.java @@ -17,7 +17,7 @@ * attrType OBJECT IDENTIFIER, * attrValues SET OF AttributeValue * } - * + * * AttributeValue ::= ANY * *

    @@ -55,7 +55,7 @@ public static Attribute getInstance( { return (Attribute)o; } - + if (o != null) { return new Attribute(ASN1Sequence.getInstance(o)); @@ -63,7 +63,7 @@ public static Attribute getInstance( return null; } - + private Attribute( ASN1Sequence seq) { @@ -83,7 +83,7 @@ public ASN1ObjectIdentifier getAttrType() { return attrType; } - + public ASN1Set getAttrValues() { return attrValues; @@ -94,7 +94,7 @@ public ASN1Encodable[] getAttributeValues() return attrValues.toArray(); } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java b/util/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java index 7550282a23..ed1ac1dc8f 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java @@ -62,7 +62,7 @@ private void addAttribute( Attribute a) { Object value = attributes.get(oid); - + if (value == null) { attributes.put(oid, a); @@ -70,28 +70,28 @@ private void addAttribute( else { Vector v; - + if (value instanceof Attribute) { v = new Vector(); - + v.addElement(value); v.addElement(a); } else { v = (Vector)value; - + v.addElement(a); } - + attributes.put(oid, v); } } /** * Return the first attribute matching the OBJECT IDENTIFIER oid. - * + * * @param oid type of attribute required. * @return first attribute found of type oid. */ @@ -99,19 +99,19 @@ public Attribute get( ASN1ObjectIdentifier oid) { Object value = attributes.get(oid); - + if (value instanceof Vector) { return (Attribute)((Vector)value).elementAt(0); } - + return (Attribute)value; } /** - * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be + * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be * empty if there are no attributes of the required type present. - * + * * @param oid type of attribute required. * @return a vector of all the attributes found of type oid. */ @@ -119,13 +119,13 @@ public ASN1EncodableVector getAll( ASN1ObjectIdentifier oid) { ASN1EncodableVector v = new ASN1EncodableVector(); - + Object value = attributes.get(oid); - + if (value instanceof Vector) { Enumeration e = ((Vector)value).elements(); - + while (e.hasMoreElements()) { v.add((Attribute)e.nextElement()); @@ -135,7 +135,7 @@ else if (value != null) { v.add((Attribute)value); } - + return v; } @@ -164,20 +164,20 @@ public Hashtable toHashtable() { return copyTable(attributes); } - + public ASN1EncodableVector toASN1EncodableVector() { ASN1EncodableVector v = new ASN1EncodableVector(); Enumeration e = attributes.elements(); - + while (e.hasMoreElements()) { Object value = e.nextElement(); - + if (value instanceof Vector) { Enumeration en = ((Vector)value).elements(); - + while (en.hasMoreElements()) { v.add(Attribute.getInstance(en.nextElement())); @@ -188,7 +188,7 @@ public ASN1EncodableVector toASN1EncodableVector() v.add(Attribute.getInstance(value)); } } - + return v; } @@ -202,14 +202,14 @@ private Hashtable copyTable( { Hashtable out = new Hashtable(); Enumeration e = in.keys(); - + while (e.hasMoreElements()) { Object key = e.nextElement(); - + out.put(key, in.get(key)); } - + return out; } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/Attributes.java b/util/src/main/java/org/bouncycastle/asn1/cms/Attributes.java index 420372a059..02b2f5e2a2 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/Attributes.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/Attributes.java @@ -25,18 +25,6 @@ public class Attributes extends ASN1Object { - private ASN1Set attributes; - - private Attributes(ASN1Set set) - { - attributes = set; - } - - public Attributes(ASN1EncodableVector v) - { - attributes = new DLSet(v); - } - /** * Return an Attribute set object from the given object. *

    @@ -64,11 +52,26 @@ else if (obj != null) return null; } - public static Attributes getInstance( - ASN1TaggedObject obj, - boolean explicit) + public static Attributes getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new Attributes(ASN1Set.getInstance(taggedObject, declaredExplicit)); + } + + public static Attributes getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new Attributes(ASN1Set.getTagged(taggedObject, declaredExplicit)); + } + + private ASN1Set attributes; + + private Attributes(ASN1Set set) + { + attributes = set; + } + + public Attributes(ASN1EncodableVector v) { - return getInstance(ASN1Set.getInstance(obj, explicit)); + attributes = new DLSet(v); } public Attribute[] getAttributes() @@ -83,7 +86,7 @@ public Attribute[] getAttributes() return rv; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java index 2454c6197d..53bb621ed5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedData.java @@ -52,7 +52,7 @@ public AuthEnvelopedData( ASN1Set unauthAttrs) { // "It MUST be set to 0." - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; this.originatorInfo = originatorInfo; diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java b/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java index c162539abe..81830e39d7 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/AuthEnvelopedDataParser.java @@ -14,7 +14,7 @@ /** * Parse {@link AuthEnvelopedData} input stream. - * + * *

      * AuthEnvelopedData ::= SEQUENCE {
      *   version CMSVersion,
    diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java
    index 8883199e28..21bfcb4e2a 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/cms/AuthenticatedData.java
    @@ -67,8 +67,8 @@ public AuthenticatedData(
                 }
             }
     
    -        version = new ASN1Integer(calculateVersion(originatorInfo));
    -        
    +        version = ASN1Integer.valueOf(calculateVersion(originatorInfo));
    +
             this.originatorInfo = originatorInfo;
             this.macAlgorithm = macAlgorithm;
             this.digestAlgorithm = digestAlgorithm;
    @@ -116,7 +116,7 @@ private AuthenticatedData(
             }
     
             mac = ASN1OctetString.getInstance(tmp);
    -        
    +
             if (seq.size() > index)
             {
                 unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
    diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java b/util/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java
    index b281d76303..a9c994c120 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/cms/CCMParameters.java
    @@ -94,7 +94,7 @@ public ASN1Primitive toASN1Primitive()
     
             if (icvLen != 12)
             {
    -            v.add(new ASN1Integer(icvLen));
    +            v.add(ASN1Integer.valueOf(icvLen));
             }
     
             return new DERSequence(v);
    diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/CMSORIforKEMOtherInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/CMSORIforKEMOtherInfo.java
    index 332a0c7630..9c483ad28f 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/cms/CMSORIforKEMOtherInfo.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/cms/CMSORIforKEMOtherInfo.java
    @@ -45,10 +45,10 @@ public CMSORIforKEMOtherInfo(AlgorithmIdentifier wrap, int kekLength, byte[] ukm
     
         public ASN1Primitive toASN1Primitive()
         {
    -        ASN1EncodableVector v = new ASN1EncodableVector();
    +        ASN1EncodableVector v = new ASN1EncodableVector(3);
     
             v.add(wrap);
    -        v.add(new ASN1Integer(kekLength));
    +        v.add(ASN1Integer.valueOf(kekLength));
     
             if (ukm != null)
             {
    diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java
    index e62afdaccf..b5f9c5fda9 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/cms/CompressedData.java
    @@ -9,9 +9,9 @@
     import org.bouncycastle.asn1.BERSequence;
     import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     
    -/** 
    +/**
      * RFC 3274: CMS Compressed Data.
    - * 
    + *
      * 
      * CompressedData ::= SEQUENCE {
      *     version CMSVersion,
    @@ -31,11 +31,11 @@ public CompressedData(
             AlgorithmIdentifier compressionAlgorithm,
             ContentInfo         encapContentInfo)
         {
    -        this.version = new ASN1Integer(0);
    +        this.version = ASN1Integer.ZERO;
             this.compressionAlgorithm = compressionAlgorithm;
             this.encapContentInfo = encapContentInfo;
         }
    -    
    +
         private CompressedData(
             ASN1Sequence seq)
         {
    @@ -59,7 +59,7 @@ public static CompressedData getInstance(
         {
             return getInstance(ASN1Sequence.getInstance(ato, isExplicit));
         }
    -    
    +
         /**
          * Return a CompressedData object from the given object.
          * 

    diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java index 53c9347311..625128ddf5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java @@ -1,7 +1,6 @@ package org.bouncycastle.asn1.cms; import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; @@ -9,7 +8,6 @@ import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERSequence; import org.bouncycastle.asn1.BERTaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DLSequence; @@ -52,8 +50,7 @@ public class ContentInfo * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ - public static ContentInfo getInstance( - Object obj) + public static ContentInfo getInstance(Object obj) { if (obj instanceof ContentInfo) { @@ -67,25 +64,30 @@ else if (obj != null) return null; } - public static ContentInfo getInstance( - ASN1TaggedObject obj, - boolean explicit) + public static ContentInfo getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - return new ContentInfo(ASN1Sequence.getInstance(obj, explicit)); + return new ContentInfo(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); } - private ContentInfo( - ASN1Sequence seq) + public static ContentInfo getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - if (seq.size() < 1 || seq.size() > 2) + return new ContentInfo(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); + } + + private ContentInfo(ASN1Sequence seq) + { + int count = seq.size(); + if (count < 1 || count > 2) { - throw new IllegalArgumentException("Bad sequence size: " + seq.size()); + throw new IllegalArgumentException("Bad sequence size: " + count); } - contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0); - if (seq.size() > 1) + this.contentType = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0)); + + ASN1Encodable content = null; + if (count > 1) { - ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1), BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject tagged = ASN1TaggedObject.getContextInstance(seq.getObjectAt(1)); if (!tagged.isExplicit() || tagged.getTagNo() != 0) { throw new IllegalArgumentException("Bad tag for 'content'"); @@ -93,10 +95,8 @@ private ContentInfo( content = tagged.getExplicitBaseObject(); } - else - { - content = null; - } + this.content = content; + isDefiniteLength = !(seq instanceof BERSequence); } @@ -151,22 +151,15 @@ public boolean isDefiniteLength() */ public ASN1Primitive toASN1Primitive() { - ASN1EncodableVector v = new ASN1EncodableVector(2); - - v.add(contentType); - - if (content != null) + if (isDefiniteLength) { - if (isDefiniteLength) - { - v.add(new DLTaggedObject(0, content)); - } - else - { - v.add(new BERTaggedObject(0, content)); - } + return content == null + ? new DLSequence(contentType) + : new DLSequence(contentType, new DLTaggedObject(0, content)); } - return isDefiniteLength ? (ASN1Primitive)new DLSequence(v) : (ASN1Primitive)new BERSequence(v); + return content == null + ? new BERSequence(contentType) + : new BERSequence(contentType, new BERTaggedObject(0, content)); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java index 9011925e88..3b4c50a46c 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/DigestedData.java @@ -12,7 +12,7 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.util.Arrays; -/** +/** * RFC 5652 DigestedData object. *

      * DigestedData ::= SEQUENCE {
    @@ -35,7 +35,7 @@ public DigestedData(
             ContentInfo encapContentInfo,
             byte[]      digest)
         {
    -        this.version = new ASN1Integer(0);
    +        this.version = ASN1Integer.ZERO;
             this.digestAlgorithm = digestAlgorithm;
             this.encapContentInfo = encapContentInfo;
             this.digest = new DEROctetString(Arrays.clone(digest));
    @@ -65,7 +65,7 @@ public static DigestedData getInstance(
         {
             return getInstance(ASN1Sequence.getInstance(ato, isExplicit));
         }
    -    
    +
         /**
          * Return a DigestedData object from the given object.
          * 

    @@ -86,12 +86,12 @@ public static DigestedData getInstance( { return (DigestedData)obj; } - + if (obj != null) { return new DigestedData(ASN1Sequence.getInstance(obj)); } - + return null; } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java index 1eaa9a715f..961e22541d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfo.java @@ -18,7 +18,7 @@ * EncryptedContentInfo ::= SEQUENCE { * contentType ContentType, * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, - * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL + * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL * } *

    */ @@ -28,9 +28,9 @@ public class EncryptedContentInfo private ASN1ObjectIdentifier contentType; private AlgorithmIdentifier contentEncryptionAlgorithm; private ASN1OctetString encryptedContent; - + public EncryptedContentInfo( - ASN1ObjectIdentifier contentType, + ASN1ObjectIdentifier contentType, AlgorithmIdentifier contentEncryptionAlgorithm, ASN1OctetString encryptedContent) { @@ -38,7 +38,7 @@ public EncryptedContentInfo( this.contentEncryptionAlgorithm = contentEncryptionAlgorithm; this.encryptedContent = encryptedContent; } - + private EncryptedContentInfo( ASN1Sequence seq) { @@ -81,7 +81,7 @@ public static EncryptedContentInfo getInstance( { return new EncryptedContentInfo(ASN1Sequence.getInstance(obj)); } - + return null; } @@ -100,13 +100,13 @@ public ASN1OctetString getEncryptedContent() return encryptedContent; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(3); - + v.add(contentType); v.add(contentEncryptionAlgorithm); @@ -114,7 +114,7 @@ public ASN1Primitive toASN1Primitive() { v.add(new BERTaggedObject(false, 0, encryptedContent)); } - + return new BERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java b/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java index 073051caf1..53e72edb1d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedContentInfoParser.java @@ -16,7 +16,7 @@ * EncryptedContentInfo ::= SEQUENCE { * contentType ContentType, * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, - * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL + * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL * } *
    */ @@ -27,26 +27,26 @@ public class EncryptedContentInfoParser private ASN1TaggedObjectParser _encryptedContent; public EncryptedContentInfoParser( - ASN1SequenceParser seq) + ASN1SequenceParser seq) throws IOException { _contentType = (ASN1ObjectIdentifier)seq.readObject(); _contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(seq.readObject().toASN1Primitive()); _encryptedContent = (ASN1TaggedObjectParser)seq.readObject(); } - + public ASN1ObjectIdentifier getContentType() { return _contentType; } - + public AlgorithmIdentifier getContentEncryptionAlgorithm() { return _contentEncryptionAlgorithm; } public ASN1Encodable getEncryptedContent( - int tag) + int tag) throws IOException { return ASN1Util.parseContextBaseUniversal(_encryptedContent, 0, false, tag); diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java index a1869749b5..9422ed6732 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/EncryptedData.java @@ -62,7 +62,7 @@ public EncryptedData(EncryptedContentInfo encInfo) public EncryptedData(EncryptedContentInfo encInfo, ASN1Set unprotectedAttrs) { - this.version = new ASN1Integer((unprotectedAttrs == null) ? 0 : 2); + this.version = unprotectedAttrs == null ? ASN1Integer.ZERO : ASN1Integer.TWO; this.encryptedContentInfo = encInfo; this.unprotectedAttrs = unprotectedAttrs; } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java index 29c4845111..2f9bc79710 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedData.java @@ -38,7 +38,7 @@ public EnvelopedData( EncryptedContentInfo encryptedContentInfo, ASN1Set unprotectedAttrs) { - version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, unprotectedAttrs)); + version = ASN1Integer.valueOf(calculateVersion(originatorInfo, recipientInfos, unprotectedAttrs)); this.originatorInfo = originatorInfo; this.recipientInfos = recipientInfos; @@ -52,7 +52,7 @@ public EnvelopedData( EncryptedContentInfo encryptedContentInfo, Attributes unprotectedAttrs) { - version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, ASN1Set.getInstance(unprotectedAttrs))); + version = ASN1Integer.valueOf(calculateVersion(originatorInfo, recipientInfos, ASN1Set.getInstance(unprotectedAttrs))); this.originatorInfo = originatorInfo; this.recipientInfos = recipientInfos; diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java b/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java index 275e7ea5a5..bb7de0a2f6 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/EnvelopedDataParser.java @@ -10,7 +10,7 @@ import org.bouncycastle.asn1.ASN1Util; import org.bouncycastle.asn1.BERTags; -/** +/** * Parser of RFC 5652 {@link EnvelopedData} object. *

    *

    @@ -19,7 +19,7 @@
      *     originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
      *     recipientInfos RecipientInfos,
      *     encryptedContentInfo EncryptedContentInfo,
    - *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL 
    + *     unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL
      * }
      * 
    */ @@ -29,7 +29,7 @@ public class EnvelopedDataParser private ASN1Integer _version; private ASN1Encodable _nextObject; private boolean _originatorInfoCalled; - + public EnvelopedDataParser( ASN1SequenceParser seq) throws IOException @@ -43,11 +43,11 @@ public ASN1Integer getVersion() return _version; } - public OriginatorInfo getOriginatorInfo() + public OriginatorInfo getOriginatorInfo() throws IOException { - _originatorInfoCalled = true; - + _originatorInfoCalled = true; + if (_nextObject == null) { _nextObject = _seq.readObject(); @@ -66,7 +66,7 @@ public OriginatorInfo getOriginatorInfo() return null; } - + public ASN1SetParser getRecipientInfos() throws IOException { @@ -74,33 +74,33 @@ public ASN1SetParser getRecipientInfos() { getOriginatorInfo(); } - + if (_nextObject == null) { _nextObject = _seq.readObject(); } - + ASN1SetParser recipientInfos = (ASN1SetParser)_nextObject; _nextObject = null; return recipientInfos; } - public EncryptedContentInfoParser getEncryptedContentInfo() + public EncryptedContentInfoParser getEncryptedContentInfo() throws IOException { if (_nextObject == null) { _nextObject = _seq.readObject(); } - - + + if (_nextObject != null) { ASN1SequenceParser o = (ASN1SequenceParser) _nextObject; _nextObject = null; return new EncryptedContentInfoParser(o); } - + return null; } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java b/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java index 474ac9b43d..a9408ed334 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/Evidence.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.tsp.EvidenceRecord; @@ -79,7 +78,7 @@ public static Evidence getInstance(Object obj) } else if (obj instanceof ASN1TaggedObject) { - return new Evidence(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC)); + return new Evidence(ASN1TaggedObject.getContextInstance(obj)); } throw new IllegalArgumentException("unknown object in getInstance"); diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java b/util/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java index 76a98dc612..e8af959613 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/GCMParameters.java @@ -94,7 +94,7 @@ public ASN1Primitive toASN1Primitive() if (icvLen != 12) { - v.add(new ASN1Integer(icvLen)); + v.add(ASN1Integer.valueOf(icvLen)); } return new DERSequence(v); diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java index 97fae7fe63..bd301f7c77 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KEKIdentifier.java @@ -18,7 +18,7 @@ * KEKIdentifier ::= SEQUENCE { * keyIdentifier OCTET STRING, * date GeneralizedTime OPTIONAL, - * other OtherKeyAttribute OPTIONAL + * other OtherKeyAttribute OPTIONAL * } *
    */ @@ -28,7 +28,7 @@ public class KEKIdentifier private ASN1OctetString keyIdentifier; private ASN1GeneralizedTime date; private OtherKeyAttribute other; - + public KEKIdentifier( byte[] keyIdentifier, ASN1GeneralizedTime date, @@ -38,12 +38,12 @@ public KEKIdentifier( this.date = date; this.other = other; } - + private KEKIdentifier( ASN1Sequence seq) { keyIdentifier = (ASN1OctetString)seq.getObjectAt(0); - + switch (seq.size()) { case 1: @@ -51,7 +51,7 @@ private KEKIdentifier( case 2: if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime) { - date = (ASN1GeneralizedTime)seq.getObjectAt(1); + date = (ASN1GeneralizedTime)seq.getObjectAt(1); } else { @@ -82,7 +82,7 @@ public static KEKIdentifier getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return a KEKIdentifier object from the given object. *

    @@ -103,12 +103,12 @@ public static KEKIdentifier getInstance( { return (KEKIdentifier)obj; } - + if (obj instanceof ASN1Sequence) { return new KEKIdentifier((ASN1Sequence)obj); } - + throw new IllegalArgumentException("Invalid KEKIdentifier: " + obj.getClass().getName()); } @@ -127,7 +127,7 @@ public OtherKeyAttribute getOther() return other; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() @@ -135,7 +135,7 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(3); v.add(keyIdentifier); - + if (date != null) { v.add(date); @@ -145,7 +145,7 @@ public ASN1Primitive toASN1Primitive() { v.add(other); } - + return new DERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java index 75802f89f6..0a257c373b 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KEKRecipientInfo.java @@ -19,7 +19,7 @@ * version CMSVersion, -- always set to 4 * kekid KEKIdentifier, * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - * encryptedKey EncryptedKey + * encryptedKey EncryptedKey * } * */ @@ -36,12 +36,12 @@ public KEKRecipientInfo( AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey) { - this.version = new ASN1Integer(4); + this.version = ASN1Integer.FOUR; this.kekid = kekid; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.encryptedKey = encryptedKey; } - + public KEKRecipientInfo( ASN1Sequence seq) { @@ -66,7 +66,7 @@ public static KEKRecipientInfo getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return a KEKRecipientInfo object from the given object. *

    @@ -87,12 +87,12 @@ public static KEKRecipientInfo getInstance( { return (KEKRecipientInfo)obj; } - + if (obj != null) { return new KEKRecipientInfo(ASN1Sequence.getInstance(obj)); } - + return null; } @@ -100,7 +100,7 @@ public ASN1Integer getVersion() { return version; } - + public KEKIdentifier getKekid() { return kekid; @@ -116,7 +116,7 @@ public ASN1OctetString getEncryptedKey() return encryptedKey; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java index 7f8e8e462c..60c617042e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KEMRecipientInfo.java @@ -56,7 +56,7 @@ public KEMRecipientInfo(RecipientIdentifier rid, AlgorithmIdentifier kem, ASN1Oc { throw new IllegalArgumentException("kekLength must be <= 65535"); } - this.cmsVersion = new ASN1Integer(0); + this.cmsVersion = ASN1Integer.ZERO; this.rid = rid; this.kem = kem; this.kemct = kemct; @@ -169,7 +169,7 @@ public ASN1Primitive toASN1Primitive() } v.add(wrap); v.add(encryptedKey); - + return new DERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java index 98ca19a504..c50c1bc1e9 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientIdentifier.java @@ -81,7 +81,7 @@ public static KeyAgreeRecipientIdentifier getInstance( } return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.getInstance(obj)); - } + } public KeyAgreeRecipientIdentifier( IssuerAndSerialNumber issuerSerial) @@ -107,7 +107,7 @@ public RecipientKeyIdentifier getRKeyID() return rKeyID; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java index b308e396f6..f82a6ea1b7 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KeyAgreeRecipientInfo.java @@ -21,7 +21,7 @@ * originator [0] EXPLICIT OriginatorIdentifierOrKey, * ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL, * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - * recipientEncryptedKeys RecipientEncryptedKeys + * recipientEncryptedKeys RecipientEncryptedKeys * } * * UserKeyingMaterial ::= OCTET STRING @@ -35,14 +35,14 @@ public class KeyAgreeRecipientInfo private ASN1OctetString ukm; private AlgorithmIdentifier keyEncryptionAlgorithm; private ASN1Sequence recipientEncryptedKeys; - + public KeyAgreeRecipientInfo( OriginatorIdentifierOrKey originator, ASN1OctetString ukm, AlgorithmIdentifier keyEncryptionAlgorithm, ASN1Sequence recipientEncryptedKeys) { - this.version = new ASN1Integer(3); + this.version = ASN1Integer.THREE; this.originator = originator; this.ukm = ukm; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; @@ -53,7 +53,7 @@ private KeyAgreeRecipientInfo( ASN1Sequence seq) { int index = 0; - + version = (ASN1Integer)seq.getObjectAt(index++); originator = OriginatorIdentifierOrKey.getInstance( (ASN1TaggedObject)seq.getObjectAt(index++), true); @@ -69,7 +69,7 @@ private KeyAgreeRecipientInfo( recipientEncryptedKeys = (ASN1Sequence)seq.getObjectAt(index++); } - + /** * Return a KeyAgreeRecipientInfo object from a tagged object. * @@ -85,7 +85,7 @@ public static KeyAgreeRecipientInfo getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return a KeyAgreeRecipientInfo object from the given object. *

    @@ -106,14 +106,14 @@ public static KeyAgreeRecipientInfo getInstance( { return (KeyAgreeRecipientInfo)obj; } - + if (obj != null) { return new KeyAgreeRecipientInfo(ASN1Sequence.getInstance(obj)); } - + return null; - } + } public ASN1Integer getVersion() { @@ -140,7 +140,7 @@ public ASN1Sequence getRecipientEncryptedKeys() return recipientEncryptedKeys; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() @@ -149,12 +149,12 @@ public ASN1Primitive toASN1Primitive() v.add(version); v.add(new DERTaggedObject(true, 0, originator)); - + if (ukm != null) { v.add(new DERTaggedObject(true, 1, ukm)); } - + v.add(keyEncryptionAlgorithm); v.add(recipientEncryptedKeys); diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java index 8b3c19e485..813928df89 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/KeyTransRecipientInfo.java @@ -18,7 +18,7 @@ * version CMSVersion, -- always set to 0 or 2 * rid RecipientIdentifier, * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - * encryptedKey EncryptedKey + * encryptedKey EncryptedKey * } * */ @@ -37,11 +37,11 @@ public KeyTransRecipientInfo( { if (rid.toASN1Primitive() instanceof ASN1TaggedObject) { - this.version = new ASN1Integer(2); + this.version = ASN1Integer.TWO; } else { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; } this.rid = rid; @@ -78,14 +78,14 @@ public static KeyTransRecipientInfo getInstance( { return (KeyTransRecipientInfo)obj; } - + if(obj != null) { return new KeyTransRecipientInfo(ASN1Sequence.getInstance(obj)); } - + return null; - } + } public ASN1Integer getVersion() { @@ -107,7 +107,7 @@ public ASN1OctetString getEncryptedKey() return encryptedKey; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/MetaData.java b/util/src/main/java/org/bouncycastle/asn1/cms/MetaData.java index 1dd7d84e26..aadd8a4b28 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/MetaData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/MetaData.java @@ -111,7 +111,7 @@ public ASN1Primitive toASN1Primitive() { v.add(otherMetaData); } - + return new DERSequence(v); } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java index de35fdb3df..d81da38d68 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorIdentifierOrKey.java @@ -18,7 +18,7 @@ * OriginatorIdentifierOrKey ::= CHOICE { * issuerAndSerialNumber IssuerAndSerialNumber, * subjectKeyIdentifier [0] SubjectKeyIdentifier, - * originatorKey [1] OriginatorPublicKey + * originatorKey [1] OriginatorPublicKey * } * * SubjectKeyIdentifier ::= OCTET STRING @@ -87,7 +87,7 @@ public static OriginatorIdentifierOrKey getInstance( return getInstance(o.getExplicitBaseObject()); } - + /** * Return an OriginatorIdentifierOrKey object from the given object. *

    @@ -154,30 +154,16 @@ public IssuerAndSerialNumber getIssuerAndSerialNumber() public SubjectKeyIdentifier getSubjectKeyIdentifier() { - if (id instanceof ASN1TaggedObject) - { - ASN1TaggedObject taggedObject = (ASN1TaggedObject)id; - if (taggedObject.hasContextTag(0)) - { - return SubjectKeyIdentifier.getInstance(taggedObject, false); - } - } + ASN1TaggedObject tag0 = ASN1TaggedObject.getContextOptional(id, 0); - return null; + return tag0 == null ? null : SubjectKeyIdentifier.getInstance(tag0, false); } public OriginatorPublicKey getOriginatorKey() { - if (id instanceof ASN1TaggedObject) - { - ASN1TaggedObject taggedObject = (ASN1TaggedObject)id; - if (taggedObject.hasContextTag(1)) - { - return OriginatorPublicKey.getInstance(taggedObject, false); - } - } + ASN1TaggedObject tag1 = ASN1TaggedObject.getContextOptional(id, 1); - return null; + return tag1 == null ? null : OriginatorPublicKey.getInstance(tag1, false); } /** diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java index 265893bf78..1c24d9bed5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorInfo.java @@ -16,7 +16,7 @@ * * OriginatorInfo ::= SEQUENCE { * certs [0] IMPLICIT CertificateSet OPTIONAL, - * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL + * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL * } * CertificateRevocationLists ::= SET OF CertificateList (from X.509) * @@ -44,7 +44,7 @@ public class OriginatorInfo { private ASN1Set certs; private ASN1Set crls; - + public OriginatorInfo( ASN1Set certs, ASN1Set crls) @@ -52,7 +52,7 @@ public OriginatorInfo( this.certs = certs; this.crls = crls; } - + private OriginatorInfo( ASN1Sequence seq) { @@ -82,7 +82,7 @@ private OriginatorInfo( throw new IllegalArgumentException("OriginatorInfo too big"); } } - + /** * Return an OriginatorInfo object from a tagged object. * @@ -98,7 +98,7 @@ public static OriginatorInfo getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return an OriginatorInfo object from the given object. *

    @@ -126,7 +126,7 @@ else if (obj != null) return null; } - + public ASN1Set getCertificates() { return certs; @@ -137,7 +137,7 @@ public ASN1Set getCRLs() return crls; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() @@ -148,12 +148,12 @@ public ASN1Primitive toASN1Primitive() { v.add(new DERTaggedObject(false, 0, certs)); } - + if (crls != null) { v.add(new DERTaggedObject(false, 1, crls)); } - + return new DERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java index 7719ef009c..a22f6f2c7e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OriginatorPublicKey.java @@ -16,7 +16,7 @@ *

      * OriginatorPublicKey ::= SEQUENCE {
      *     algorithm AlgorithmIdentifier,
    - *     publicKey BIT STRING 
    + *     publicKey BIT STRING
      * }
      * 
    */ @@ -48,7 +48,7 @@ private OriginatorPublicKey( algorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0)); publicKey = (DERBitString)seq.getObjectAt(1); } - + /** * Return an OriginatorPublicKey object from a tagged object. * @@ -64,7 +64,7 @@ public static OriginatorPublicKey getInstance( { return new OriginatorPublicKey(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return an OriginatorPublicKey object from the given object. *

    @@ -85,14 +85,14 @@ public static OriginatorPublicKey getInstance( { return (OriginatorPublicKey)obj; } - + if (obj != null) { return new OriginatorPublicKey(ASN1Sequence.getInstance(obj)); } return null; - } + } public AlgorithmIdentifier getAlgorithm() { @@ -112,7 +112,7 @@ public ASN1BitString getPublicKeyData() return publicKey; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java b/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java index ca97ae7dc8..4d8c010d53 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OtherKeyAttribute.java @@ -44,7 +44,7 @@ public static OtherKeyAttribute getInstance( { return (OtherKeyAttribute)o; } - + if (o != null) { return new OtherKeyAttribute(ASN1Sequence.getInstance(o)); @@ -76,13 +76,13 @@ public ASN1ObjectIdentifier getKeyAttrId() { return keyAttrId; } - + public ASN1Encodable getKeyAttr() { return keyAttr; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java index 90db62699f..136db01697 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OtherRecipientInfo.java @@ -30,7 +30,7 @@ public OtherRecipientInfo( this.oriType = oriType; this.oriValue = oriValue; } - + private OtherRecipientInfo( ASN1Sequence seq) { @@ -53,7 +53,7 @@ public static OtherRecipientInfo getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return a OtherRecipientInfo object from the given object. *

    @@ -74,12 +74,12 @@ public static OtherRecipientInfo getInstance( { return (OtherRecipientInfo)obj; } - + if (obj != null) { return new OtherRecipientInfo(ASN1Sequence.getInstance(obj)); } - + return null; } @@ -93,7 +93,7 @@ public ASN1Encodable getValue() return oriValue; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java b/util/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java index c65daca9ca..6457b394d2 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/OtherRevocationInfoFormat.java @@ -53,7 +53,7 @@ public static OtherRevocationInfoFormat getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return a OtherRevocationInfoFormat object from the given object. *

    @@ -74,12 +74,12 @@ public static OtherRevocationInfoFormat getInstance( { return (OtherRevocationInfoFormat)obj; } - + if (obj != null) { return new OtherRevocationInfoFormat(ASN1Sequence.getInstance(obj)); } - + return null; } @@ -93,7 +93,7 @@ public ASN1Encodable getInfo() return otherRevInfo; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java index fac02bb4a0..e44f1a0aba 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/PasswordRecipientInfo.java @@ -35,17 +35,17 @@ public PasswordRecipientInfo( AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey) { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.encryptedKey = encryptedKey; } - + public PasswordRecipientInfo( AlgorithmIdentifier keyDerivationAlgorithm, AlgorithmIdentifier keyEncryptionAlgorithm, ASN1OctetString encryptedKey) { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; this.keyDerivationAlgorithm = keyDerivationAlgorithm; this.keyEncryptionAlgorithm = keyEncryptionAlgorithm; this.encryptedKey = encryptedKey; @@ -83,7 +83,7 @@ public static PasswordRecipientInfo getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return a PasswordRecipientInfo object from the given object. *

    @@ -104,12 +104,12 @@ public static PasswordRecipientInfo getInstance( { return (PasswordRecipientInfo)obj; } - + if (obj != null) { return new PasswordRecipientInfo(ASN1Sequence.getInstance(obj)); } - + return null; } @@ -133,7 +133,7 @@ public ASN1OctetString getEncryptedKey() return encryptedKey; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() @@ -141,7 +141,7 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(4); v.add(version); - + if (keyDerivationAlgorithm != null) { v.add(new DERTaggedObject(false, 0, keyDerivationAlgorithm)); diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java index 2e06e0b902..3abc309b33 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientEncryptedKey.java @@ -29,7 +29,7 @@ private RecipientEncryptedKey( identifier = KeyAgreeRecipientIdentifier.getInstance(seq.getObjectAt(0)); encryptedKey = (ASN1OctetString)seq.getObjectAt(1); } - + /** * Return an RecipientEncryptedKey object from a tagged object. * @@ -45,7 +45,7 @@ public static RecipientEncryptedKey getInstance( { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } - + /** * Return a RecipientEncryptedKey object from the given object. *

    @@ -66,14 +66,14 @@ public static RecipientEncryptedKey getInstance( { return (RecipientEncryptedKey)obj; } - + if (obj != null) { return new RecipientEncryptedKey(ASN1Sequence.getInstance(obj)); } - + return null; - } + } public RecipientEncryptedKey( KeyAgreeRecipientIdentifier id, @@ -93,7 +93,7 @@ public ASN1OctetString getEncryptedKey() return encryptedKey; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java index 5a03d4c862..b7f0008c91 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientIdentifier.java @@ -14,7 +14,7 @@ *

      * RecipientIdentifier ::= CHOICE {
      *     issuerAndSerialNumber IssuerAndSerialNumber,
    - *     subjectKeyIdentifier [0] SubjectKeyIdentifier 
    + *     subjectKeyIdentifier [0] SubjectKeyIdentifier
      * }
      *
      * SubjectKeyIdentifier ::= OCTET STRING
    @@ -25,25 +25,25 @@ public class RecipientIdentifier
         implements ASN1Choice
     {
         private ASN1Encodable id;
    -    
    +
         public RecipientIdentifier(
             IssuerAndSerialNumber id)
         {
             this.id = id;
         }
    -    
    +
         public RecipientIdentifier(
             ASN1OctetString id)
         {
             this.id = new DERTaggedObject(false, 0, id);
         }
    -    
    +
         public RecipientIdentifier(
             ASN1Primitive id)
         {
             this.id = id;
         }
    -    
    +
         /**
          * Return a RecipientIdentifier object from the given object.
          * 

    @@ -66,25 +66,25 @@ public static RecipientIdentifier getInstance( { return (RecipientIdentifier)o; } - + if (o instanceof IssuerAndSerialNumber) { return new RecipientIdentifier((IssuerAndSerialNumber)o); } - + if (o instanceof ASN1OctetString) { return new RecipientIdentifier((ASN1OctetString)o); } - + if (o instanceof ASN1Primitive) { return new RecipientIdentifier((ASN1Primitive)o); } - + throw new IllegalArgumentException( "Illegal object in RecipientIdentifier: " + o.getClass().getName()); - } + } public boolean isTagged() { @@ -101,7 +101,7 @@ public ASN1Encodable getId() return IssuerAndSerialNumber.getInstance(id); } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java index 23f6c0a043..61fadc756f 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientInfo.java @@ -118,7 +118,7 @@ public ASN1Integer getVersion() case 3: return PasswordRecipientInfo.getInstance(tagged, false).getVersion(); case 4: - return new ASN1Integer(0); // no syntax version for OtherRecipientInfo + return ASN1Integer.ZERO; // no syntax version for OtherRecipientInfo } } throw new IllegalStateException("unknown tag"); diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java index 9ae3163ea9..134c71b2c9 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/RecipientKeyIdentifier.java @@ -18,7 +18,7 @@ * RecipientKeyIdentifier ::= SEQUENCE { * subjectKeyIdentifier SubjectKeyIdentifier, * date GeneralizedTime OPTIONAL, - * other OtherKeyAttribute OPTIONAL + * other OtherKeyAttribute OPTIONAL * } * * SubjectKeyIdentifier ::= OCTET STRING @@ -62,7 +62,7 @@ private RecipientKeyIdentifier( { subjectKeyIdentifier = ASN1OctetString.getInstance( seq.getObjectAt(0)); - + switch(seq.size()) { case 1: @@ -99,7 +99,7 @@ public static RecipientKeyIdentifier getInstance(ASN1TaggedObject ato, boolean i { return getInstance(ASN1Sequence.getInstance(ato, isExplicit)); } - + /** * Return a RecipientKeyIdentifier object from the given object. *

    @@ -119,14 +119,14 @@ public static RecipientKeyIdentifier getInstance(Object obj) { return (RecipientKeyIdentifier)obj; } - + if(obj != null) { return new RecipientKeyIdentifier(ASN1Sequence.getInstance(obj)); } - + return null; - } + } public ASN1OctetString getSubjectKeyIdentifier() { @@ -144,7 +144,7 @@ public OtherKeyAttribute getOtherKeyAttribute() } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() @@ -152,7 +152,7 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(3); v.add(subjectKeyIdentifier); - + if (date != null) { v.add(date); @@ -162,7 +162,7 @@ public ASN1Primitive toASN1Primitive() { v.add(other); } - + return new DERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java b/util/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java index b1e4a370e6..2af1846e54 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/SCVPReqRes.java @@ -1,6 +1,5 @@ package org.bouncycastle.asn1.cms; -import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; @@ -37,8 +36,7 @@ public class SCVPReqRes * @param obj the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ - public static SCVPReqRes getInstance( - Object obj) + public static SCVPReqRes getInstance(Object obj) { if (obj instanceof SCVPReqRes) { @@ -52,29 +50,57 @@ else if (obj != null) return null; } - private SCVPReqRes( - ASN1Sequence seq) + public static SCVPReqRes getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) { - if (seq.getObjectAt(0) instanceof ASN1TaggedObject) + return new SCVPReqRes(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); + } + + public static SCVPReqRes getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new SCVPReqRes(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); + } + + private SCVPReqRes(ASN1Sequence seq) + { + int count = seq.size(), pos = 0; + if (count < 1 || count > 2) + { + throw new IllegalArgumentException("Bad sequence size: " + count); + } + + // request [0] EXPLICIT ContentInfo OPTIONAL + ContentInfo request = null; + if (pos < count) { - this.request = ContentInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(0)), true); - this.response = ContentInfo.getInstance(seq.getObjectAt(1)); + ASN1TaggedObject tag0 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 0); + if (tag0 != null) + { + pos++; + request = ContentInfo.getTagged(tag0, true); + } } - else + this.request = request; + + this.response = ContentInfo.getInstance(seq.getObjectAt(pos++)); + + if (pos != count) { - this.request = null; - this.response = ContentInfo.getInstance(seq.getObjectAt(0)); + throw new IllegalArgumentException("Unexpected elements in sequence"); } } public SCVPReqRes(ContentInfo response) { - this.request = null; // use of this confuses earlier JDKs - this.response = response; + this(null, response); } public SCVPReqRes(ContentInfo request, ContentInfo response) { + if (response == null) + { + throw new NullPointerException("'response' cannot be null"); + } + this.request = request; this.response = response; } @@ -94,15 +120,11 @@ public ContentInfo getResponse() */ public ASN1Primitive toASN1Primitive() { - ASN1EncodableVector v = new ASN1EncodableVector(2); - - if (request != null) + if (request == null) { - v.add(new DERTaggedObject(true, 0, request)); + return new DERSequence(response); } - v.add(response); - - return new DERSequence(v); + return new DERSequence(new DERTaggedObject(true, 0, request), response); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/SignedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/SignedData.java index b354c5649a..8f50ced510 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/SignedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/SignedData.java @@ -29,9 +29,9 @@ * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, * signerInfos SignerInfos * } - * + * * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier - * + * * SignerInfos ::= SET OF SignerInfo *

    *

    @@ -59,11 +59,6 @@ public class SignedData extends ASN1Object { - private static final ASN1Integer VERSION_1 = new ASN1Integer(1); - private static final ASN1Integer VERSION_3 = new ASN1Integer(3); - private static final ASN1Integer VERSION_4 = new ASN1Integer(4); - private static final ASN1Integer VERSION_5 = new ASN1Integer(5); - private final ASN1Integer version; private final ASN1Set digestAlgorithms; private final ContentInfo contentInfo; @@ -163,7 +158,7 @@ else if (tagged.getTagNo() == 3) if (otherCert) { - return new ASN1Integer(5); + return ASN1Integer.FIVE; } if (crls != null) // no need to check if otherCert is true @@ -180,30 +175,30 @@ else if (tagged.getTagNo() == 3) if (otherCrl) { - return VERSION_5; + return ASN1Integer.FIVE; } if (attrCertV2Found) { - return VERSION_4; + return ASN1Integer.FOUR; } if (attrCertV1Found) { - return VERSION_3; + return ASN1Integer.THREE; } if (checkForVersion3(signerInfs)) { - return VERSION_3; + return ASN1Integer.THREE; } if (!CMSObjectIdentifiers.data.equals(contentOid)) { - return VERSION_3; + return ASN1Integer.THREE; } - return VERSION_1; + return ASN1Integer.ONE; } private boolean checkForVersion3(ASN1Set signerInfs) @@ -344,7 +339,7 @@ public ASN1Primitive toASN1Primitive() } v.add(signerInfos); - + if (!contentInfo.isDefiniteLength() || digsBer || sigsBer || crlsBer || certsBer) { return new BERSequence(v); diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java index d5681483fc..49ef0b3950 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/SignerIdentifier.java @@ -17,7 +17,7 @@ *

      * SignerIdentifier ::= CHOICE {
      *     issuerAndSerialNumber IssuerAndSerialNumber,
    - *     subjectKeyIdentifier [0] SubjectKeyIdentifier 
    + *     subjectKeyIdentifier [0] SubjectKeyIdentifier
      * }
      *
      * SubjectKeyIdentifier ::= OCTET STRING
    @@ -28,25 +28,25 @@ public class SignerIdentifier
         implements ASN1Choice
     {
         private ASN1Encodable id;
    -    
    +
         public SignerIdentifier(
             IssuerAndSerialNumber id)
         {
             this.id = id;
         }
    -    
    +
         public SignerIdentifier(
             ASN1OctetString id)
         {
             this.id = new DERTaggedObject(false, 0, id);
         }
    -    
    +
         public SignerIdentifier(
             ASN1Primitive id)
         {
             this.id = id;
         }
    -    
    +
         /**
          * Return a SignerIdentifier object from the given object.
          * 

    @@ -69,25 +69,25 @@ public static SignerIdentifier getInstance( { return (SignerIdentifier)o; } - + if (o instanceof IssuerAndSerialNumber) { return new SignerIdentifier((IssuerAndSerialNumber)o); } - + if (o instanceof ASN1OctetString) { return new SignerIdentifier((ASN1OctetString)o); } - + if (o instanceof ASN1Primitive) { return new SignerIdentifier((ASN1Primitive)o); } - + throw new IllegalArgumentException( "Illegal object in SignerIdentifier: " + o.getClass().getName()); - } + } public boolean isTagged() { @@ -104,7 +104,7 @@ public ASN1Encodable getId() return id; } - /** + /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java b/util/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java index 491bb91b20..f88ff37aec 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java @@ -62,13 +62,13 @@ * * SignedAttributes ::= SET SIZE (1..MAX) OF Attribute * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute - * + * * {@link Attribute} ::= SEQUENCE { * attrType OBJECT IDENTIFIER, * attrValues SET OF AttributeValue } * * AttributeValue ::= ANY - * + * * SignatureValue ::= OCTET STRING *

    */ @@ -131,11 +131,11 @@ public SignerInfo( { if (sid.isTagged()) { - this.version = new ASN1Integer(3); + this.version = ASN1Integer.THREE; } else { - this.version = new ASN1Integer(1); + this.version = ASN1Integer.ONE; } this.sid = sid; @@ -165,11 +165,11 @@ public SignerInfo( { if (sid.isTagged()) { - this.version = new ASN1Integer(3); + this.version = ASN1Integer.THREE; } else { - this.version = new ASN1Integer(1); + this.version = ASN1Integer.ONE; } this.sid = sid; diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/Time.java b/util/src/main/java/org/bouncycastle/asn1/cms/Time.java index ecc9b199c6..b260b736a6 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/Time.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/Time.java @@ -59,7 +59,7 @@ private Time( throw new IllegalArgumentException("unknown object passed to Time"); } - this.time = time; + this.time = time; } /** diff --git a/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java b/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java index 94ba67c568..5590d5dcbb 100644 --- a/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java +++ b/util/src/main/java/org/bouncycastle/asn1/cms/TimeStampedData.java @@ -35,7 +35,7 @@ public class TimeStampedData public TimeStampedData(ASN1IA5String dataUri, MetaData metaData, ASN1OctetString content, Evidence temporalEvidence) { - this.version = new ASN1Integer(1); + this.version = ASN1Integer.ONE; this.dataUri = dataUri; this.metaData = metaData; this.content = content; diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/CertRequest.java b/util/src/main/java/org/bouncycastle/asn1/crmf/CertRequest.java index f7f0adf571..caeba6346c 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/CertRequest.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/CertRequest.java @@ -43,7 +43,7 @@ public CertRequest( CertTemplate certTemplate, Controls controls) { - this(new ASN1Integer(certReqId), certTemplate, controls); + this(ASN1Integer.valueOf(certReqId), certTemplate, controls); } public CertRequest( diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/CertTemplateBuilder.java b/util/src/main/java/org/bouncycastle/asn1/crmf/CertTemplateBuilder.java index 305b6727da..256ba0648b 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/CertTemplateBuilder.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/CertTemplateBuilder.java @@ -28,7 +28,7 @@ public class CertTemplateBuilder /** Sets the X.509 version. Note: for X509v3, use 2 here. */ public CertTemplateBuilder setVersion(int ver) { - version = new ASN1Integer(ver); + version = ASN1Integer.valueOf(ver); return this; } diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/EncKeyWithID.java b/util/src/main/java/org/bouncycastle/asn1/crmf/EncKeyWithID.java index 2e3ca95895..0320ca2d14 100644 --- a/util/src/main/java/org/bouncycastle/asn1/crmf/EncKeyWithID.java +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/EncKeyWithID.java @@ -89,7 +89,7 @@ public ASN1Encodable getIdentifier() { return identifier; } - + /** *
          * EncKeyWithID ::= SEQUENCE {
    diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java b/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java
    index e97bcbea8a..17420cb130 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/PKIArchiveOptions.java
    @@ -7,7 +7,6 @@
     import org.bouncycastle.asn1.ASN1OctetString;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
     public class PKIArchiveOptions
    @@ -28,7 +27,7 @@ public static PKIArchiveOptions getInstance(Object o)
             }
             else if (o instanceof ASN1TaggedObject)
             {
    -            return new PKIArchiveOptions(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new PKIArchiveOptions(ASN1TaggedObject.getContextInstance(o));
             }
     
             throw new IllegalArgumentException("unknown object: " + o);
    @@ -86,7 +85,7 @@ public ASN1Encodable getValue()
         {
             return value;
         }
    -    
    +
         /**
          * 
          *  PKIArchiveOptions ::= CHOICE {
    diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/PKIPublicationInfo.java b/util/src/main/java/org/bouncycastle/asn1/crmf/PKIPublicationInfo.java
    index 5f597059de..352f891ec9 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/crmf/PKIPublicationInfo.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/PKIPublicationInfo.java
    @@ -24,8 +24,8 @@
     public class PKIPublicationInfo
         extends ASN1Object
     {
    -    public static final ASN1Integer dontPublish = new ASN1Integer(0);
    -    public static final ASN1Integer pleasePublish = new ASN1Integer(1);
    +    public static final ASN1Integer dontPublish = ASN1Integer.ZERO;
    +    public static final ASN1Integer pleasePublish = ASN1Integer.ONE;
     
         private ASN1Integer action;
         private ASN1Sequence pubInfos;
    diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/SinglePubInfo.java b/util/src/main/java/org/bouncycastle/asn1/crmf/SinglePubInfo.java
    index cf3dcd004c..5248316be9 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/crmf/SinglePubInfo.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/SinglePubInfo.java
    @@ -22,10 +22,10 @@
     public class SinglePubInfo
         extends ASN1Object
     {
    -    public static final ASN1Integer dontCare = new ASN1Integer(0);
    -    public static final ASN1Integer x500 = new ASN1Integer(1);
    -    public static final ASN1Integer web = new ASN1Integer(2);
    -    public static final ASN1Integer ldap = new ASN1Integer(3);
    +    public static final ASN1Integer dontCare = ASN1Integer.valueOf(0);
    +    public static final ASN1Integer x500 = ASN1Integer.valueOf(1);
    +    public static final ASN1Integer web = ASN1Integer.valueOf(2);
    +    public static final ASN1Integer ldap = ASN1Integer.valueOf(3);
     
         private ASN1Integer pubMethod;
         private GeneralName pubLocation;
    diff --git a/util/src/main/java/org/bouncycastle/asn1/crmf/SubsequentMessage.java b/util/src/main/java/org/bouncycastle/asn1/crmf/SubsequentMessage.java
    index 4691722855..743262f7ba 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/crmf/SubsequentMessage.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/crmf/SubsequentMessage.java
    @@ -7,7 +7,7 @@ public class SubsequentMessage
     {
         public static final SubsequentMessage encrCert = new SubsequentMessage(0);
         public static final SubsequentMessage challengeResp = new SubsequentMessage(1);
    -    
    +
         private SubsequentMessage(int value)
         {
             super(value);
    diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java
    index c54c03c185..75e2d7915b 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/CertEtcToken.java
    @@ -6,7 +6,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     import org.bouncycastle.asn1.cmp.PKIStatusInfo;
     import org.bouncycastle.asn1.cms.ContentInfo;
    @@ -116,7 +115,7 @@ public static CertEtcToken getInstance(Object obj)
             }
             else if (obj instanceof ASN1TaggedObject)
             {
    -            return new CertEtcToken(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC));
    +            return new CertEtcToken(ASN1TaggedObject.getContextInstance(obj));
             }
             else if (obj != null)
             {
    diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfo.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfo.java
    index c29dfe64aa..42ab3bf0a7 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfo.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfo.java
    @@ -158,7 +158,7 @@ public ASN1Primitive toASN1Primitive()
     
             if (version != DEFAULT_VERSION)
             {
    -            v.add(new ASN1Integer(version));
    +            v.add(ASN1Integer.valueOf(version));
             }
             v.add(dvReqInfo);
             v.add(messageImprint);
    diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfoBuilder.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfoBuilder.java
    index ab4ab4ffd8..2d2e5df876 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfoBuilder.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSCertInfoBuilder.java
    @@ -67,7 +67,7 @@ public DVCSCertInfo build()
     
             if (version != DEFAULT_VERSION)
             {
    -            v.add(new ASN1Integer(version));
    +            v.add(ASN1Integer.valueOf(version));
             }
             v.add(dvReqInfo);
             v.add(messageImprint);
    diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformation.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformation.java
    index 1606528e14..645bb2e121 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformation.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformation.java
    @@ -142,7 +142,7 @@ public ASN1Primitive toASN1Primitive()
     
             if (version != DEFAULT_VERSION)
             {
    -            v.add(new ASN1Integer(version));
    +            v.add(ASN1Integer.valueOf(version));
             }
             v.add(service);
             if (nonce != null)
    diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformationBuilder.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformationBuilder.java
    index dafb58f6a7..d4efbc19d1 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformationBuilder.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSRequestInformationBuilder.java
    @@ -73,7 +73,7 @@ public DVCSRequestInformation build()
     
             if (version != DEFAULT_VERSION)
             {
    -            v.add(new ASN1Integer(version));
    +            v.add(ASN1Integer.valueOf(version));
             }
             v.add(service);
             if (nonce != null)
    diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java
    index 2ad99baeb6..3ae2a98909 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/DVCSTime.java
    @@ -7,7 +7,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.cms.ContentInfo;
     
     /**
    @@ -71,7 +70,7 @@ public static DVCSTime getInstance(
                 throw new IllegalArgumentException("choice item must be explicitly tagged");
             }
     
    -        return getInstance(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC).getExplicitBaseObject()); // must be explicitly tagged
    +        return getInstance(ASN1TaggedObject.getContextInstance(obj).getExplicitBaseObject()); // must be explicitly tagged
         }
     
     
    diff --git a/util/src/main/java/org/bouncycastle/asn1/dvcs/PathProcInput.java b/util/src/main/java/org/bouncycastle/asn1/dvcs/PathProcInput.java
    index 4301fdb5d7..e0868c8b36 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/dvcs/PathProcInput.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/dvcs/PathProcInput.java
    @@ -119,7 +119,7 @@ public ASN1Primitive toASN1Primitive()
                 {
                     pV.add(acceptablePolicySet[i]);
                 }
    -    
    +
                 v.add(new DERSequence(pV));
             }
     
    diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/ECDSAPublicKey.java b/util/src/main/java/org/bouncycastle/asn1/eac/ECDSAPublicKey.java
    index 5b016b6a92..4acec9f496 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/eac/ECDSAPublicKey.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/eac/ECDSAPublicKey.java
    @@ -59,7 +59,7 @@ public class ECDSAPublicKey
             while (en.hasMoreElements())
             {
                 Object obj = en.nextElement();
    -            
    +
                 if (obj instanceof ASN1TaggedObject)
                 {
                     ASN1TaggedObject to = (ASN1TaggedObject)obj;
    diff --git a/util/src/main/java/org/bouncycastle/asn1/eac/PackedDate.java b/util/src/main/java/org/bouncycastle/asn1/eac/PackedDate.java
    index 143040ba86..05e619466a 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/eac/PackedDate.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/eac/PackedDate.java
    @@ -105,7 +105,7 @@ public boolean equals(Object o)
             return Arrays.areEqual(time, other.time);
         }
     
    -    public String toString() 
    +    public String toString()
         {
             char[]  dateC = new char[time.length];
     
    diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeIndication.java b/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeIndication.java
    index 2bb9c60c21..95ddaa6d4d 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeIndication.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeIndication.java
    @@ -12,7 +12,7 @@ public class CommitmentTypeIndication
     {
         private ASN1ObjectIdentifier   commitmentTypeId;
         private ASN1Sequence          commitmentTypeQualifier;
    -    
    +
         private CommitmentTypeIndication(
             ASN1Sequence seq)
         {
    @@ -53,12 +53,12 @@ public ASN1ObjectIdentifier getCommitmentTypeId()
         {
             return commitmentTypeId;
         }
    -    
    +
         public ASN1Sequence getCommitmentTypeQualifier()
         {
             return commitmentTypeQualifier;
         }
    -    
    +
         /**
          * 
          * CommitmentTypeIndication ::= SEQUENCE {
    @@ -66,18 +66,18 @@ public ASN1Sequence getCommitmentTypeQualifier()
          *      commitmentTypeQualifier   SEQUENCE SIZE (1..MAX) OF
          *              CommitmentTypeQualifier OPTIONAL }
          * 
    - */ + */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(2); - + v.add(commitmentTypeId); if (commitmentTypeQualifier != null) { v.add(commitmentTypeQualifier); } - + return new DERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeQualifier.java b/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeQualifier.java index f826bb035f..bc08e6a73d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeQualifier.java +++ b/util/src/main/java/org/bouncycastle/asn1/esf/CommitmentTypeQualifier.java @@ -10,7 +10,7 @@ /** * Commitment type qualifiers, used in the Commitment-Type-Indication attribute (RFC3126). - * + * *
      *   CommitmentTypeQualifier ::= SEQUENCE {
      *       commitmentTypeIdentifier  CommitmentTypeIdentifier,
    @@ -33,7 +33,7 @@ public CommitmentTypeQualifier(
         {
             this(commitmentTypeIdentifier, null);
         }
    -    
    +
        /**
         * Creates a new CommitmentTypeQualifier instance.
         *
    @@ -52,13 +52,13 @@ public CommitmentTypeQualifier(
          * Creates a new CommitmentTypeQualifier instance.
          *
          * @param as CommitmentTypeQualifier structure
    -     * encoded as an ASN1Sequence. 
    +     * encoded as an ASN1Sequence.
          */
         private CommitmentTypeQualifier(
             ASN1Sequence as)
         {
             commitmentTypeIdentifier = (ASN1ObjectIdentifier)as.getObjectAt(0);
    -        
    +
             if (as.size() > 1)
             {
                 qualifier = as.getObjectAt(1);
    @@ -83,14 +83,14 @@ public ASN1ObjectIdentifier getCommitmentTypeIdentifier()
         {
             return commitmentTypeIdentifier;
         }
    -    
    +
         public ASN1Encodable getQualifier()
         {
             return qualifier;
         }
     
        /**
    -    * Returns a DER-encodable representation of this instance. 
    +    * Returns a DER-encodable representation of this instance.
         *
         * @return a ASN1Primitive value
         */
    diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/CrlIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/esf/CrlIdentifier.java
    index 99d5fdbd4d..276152d818 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/esf/CrlIdentifier.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/esf/CrlIdentifier.java
    @@ -13,7 +13,7 @@
     
     /**
      * 
    - *  CrlIdentifier ::= SEQUENCE 
    + *  CrlIdentifier ::= SEQUENCE
      * {
      *   crlissuer    Name,
      *   crlIssuedTime  UTCTime,
    diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java b/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java
    index b81dc6176a..4af28ed6da 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/esf/CrlOcspRef.java
    @@ -7,7 +7,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.DERTaggedObject;
     
    @@ -47,7 +46,7 @@ private CrlOcspRef(ASN1Sequence seq)
             Enumeration e = seq.getObjects();
             while (e.hasMoreElements())
             {
    -            ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC);
    +            ASN1TaggedObject o = ASN1TaggedObject.getContextInstance(e.nextElement());
                 switch (o.getTagNo())
                 {
                     case 0:
    diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java b/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java
    index 7196a38bf6..82335b1590 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/esf/RevocationValues.java
    @@ -7,7 +7,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.DERTaggedObject;
     import org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
    @@ -53,7 +52,7 @@ private RevocationValues(ASN1Sequence seq)
             Enumeration e = seq.getObjects();
             while (e.hasMoreElements())
             {
    -            ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC);
    +            ASN1TaggedObject o = ASN1TaggedObject.getContextInstance(e.nextElement());
                 switch (o.getTagNo())
                 {
                     case 0:
    diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java b/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java
    index 1a2132446f..cad7edae37 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/esf/SignerLocation.java
    @@ -8,7 +8,6 @@
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
     import org.bouncycastle.asn1.ASN1UTF8String;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.DERTaggedObject;
     import org.bouncycastle.asn1.DERUTF8String;
    @@ -16,7 +15,7 @@
     
     /**
      * Signer-Location attribute (RFC3126).
    - * 
    + *
      * 
      *   SignerLocation ::= SEQUENCE {
      *       countryName        [0] DirectoryString OPTIONAL,
    @@ -32,7 +31,7 @@ public class SignerLocation
         private DirectoryString   countryName;
         private DirectoryString   localityName;
         private ASN1Sequence      postalAddress;
    -    
    +
         private SignerLocation(
             ASN1Sequence seq)
         {
    @@ -40,7 +39,7 @@ private SignerLocation(
     
             while (e.hasMoreElements())
             {
    -            ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC);
    +            ASN1TaggedObject o = ASN1TaggedObject.getContextInstance(e.nextElement());
     
                 switch (o.getTagNo())
                 {
    @@ -190,7 +189,7 @@ public ASN1Sequence getPostalAddress()
          *       postalAddress      [2] PostalAddress OPTIONAL }
          *
          *   PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
    -     *   
    +     *
          *   DirectoryString ::= CHOICE {
          *         teletexString           TeletexString (SIZE (1..MAX)),
          *         printableString         PrintableString (SIZE (1..MAX)),
    diff --git a/util/src/main/java/org/bouncycastle/asn1/esf/package-info.java b/util/src/main/java/org/bouncycastle/asn1/esf/package-info.java
    index ebbdcc0d61..9d55e4f7fc 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/esf/package-info.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/esf/package-info.java
    @@ -1,5 +1,5 @@
     /**
    - * Support classes useful for encoding and supporting [ESF] RFC3126 
    + * Support classes useful for encoding and supporting [ESF] RFC3126
      * Electronic Signature Formats for long term electronic signatures.
      */
     package org.bouncycastle.asn1.esf;
    diff --git a/util/src/main/java/org/bouncycastle/asn1/ess/ContentIdentifier.java b/util/src/main/java/org/bouncycastle/asn1/ess/ContentIdentifier.java
    index 37064c4e20..4781795de8 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/ess/ContentIdentifier.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/ess/ContentIdentifier.java
    @@ -41,7 +41,7 @@ public ContentIdentifier(
         {
             this(new DEROctetString(value));
         }
    -    
    +
         public ASN1OctetString getValue()
         {
             return value;
    diff --git a/util/src/main/java/org/bouncycastle/asn1/ess/ESSCertID.java b/util/src/main/java/org/bouncycastle/asn1/ess/ESSCertID.java
    index ec09ba01f2..2bb78394a9 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/ess/ESSCertID.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/ess/ESSCertID.java
    @@ -42,7 +42,7 @@ private ESSCertID(ASN1Sequence seq)
             }
     
             certHash = ASN1OctetString.getInstance(seq.getObjectAt(0));
    - 
    +
             if (seq.size() > 1)
             {
                 issuerSerial = IssuerSerial.getInstance(seq.getObjectAt(1));
    @@ -92,16 +92,16 @@ public IssuerSerial getIssuerSerial()
         /**
          * 
          * ESSCertID ::= SEQUENCE {
    -     *     certHash Hash, 
    +     *     certHash Hash,
          *     issuerSerial IssuerSerial OPTIONAL }
          * 
    */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(2); - + v.add(certHash); - + if (issuerSerial != null) { v.add(issuerSerial); diff --git a/util/src/main/java/org/bouncycastle/asn1/ess/SigningCertificate.java b/util/src/main/java/org/bouncycastle/asn1/ess/SigningCertificate.java index d5388c51a4..a867ec17b9 100644 --- a/util/src/main/java/org/bouncycastle/asn1/ess/SigningCertificate.java +++ b/util/src/main/java/org/bouncycastle/asn1/ess/SigningCertificate.java @@ -39,7 +39,7 @@ private SigningCertificate(ASN1Sequence seq) + seq.size()); } this.certs = ASN1Sequence.getInstance(seq.getObjectAt(0)); - + if (seq.size() > 1) { this.policies = ASN1Sequence.getInstance(seq.getObjectAt(1)); @@ -55,32 +55,32 @@ public SigningCertificate( public ESSCertID[] getCerts() { ESSCertID[] cs = new ESSCertID[certs.size()]; - + for (int i = 0; i != certs.size(); i++) { cs[i] = ESSCertID.getInstance(certs.getObjectAt(i)); } - + return cs; } - + public PolicyInformation[] getPolicies() { if (policies == null) { return null; } - + PolicyInformation[] ps = new PolicyInformation[policies.size()]; - + for (int i = 0; i != policies.size(); i++) { ps[i] = PolicyInformation.getInstance(policies.getObjectAt(i)); } - + return ps; } - + /** * The definition of SigningCertificate is *
    @@ -98,12 +98,12 @@ public ASN1Primitive toASN1Primitive()
             ASN1EncodableVector v = new ASN1EncodableVector(2);
     
             v.add(certs);
    -        
    +
             if (policies != null)
             {
                 v.add(policies);
             }
    -        
    +
             return new DERSequence(v);
         }
     }
    diff --git a/util/src/main/java/org/bouncycastle/asn1/icao/CscaMasterList.java b/util/src/main/java/org/bouncycastle/asn1/icao/CscaMasterList.java
    index 50f8351f36..636992e875 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/icao/CscaMasterList.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/icao/CscaMasterList.java
    @@ -25,7 +25,7 @@
     public class CscaMasterList
         extends ASN1Object
     {
    -    private ASN1Integer version = new ASN1Integer(0);
    +    private ASN1Integer version = ASN1Integer.ZERO;
         private Certificate[] certList;
     
         public static CscaMasterList getInstance(
    diff --git a/util/src/main/java/org/bouncycastle/asn1/icao/DataGroupHash.java b/util/src/main/java/org/bouncycastle/asn1/icao/DataGroupHash.java
    index ae86174364..64a4e9feaa 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/icao/DataGroupHash.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/icao/DataGroupHash.java
    @@ -15,7 +15,7 @@
      * DataGroupHash  ::=  SEQUENCE {
      *      dataGroupNumber         DataGroupNumber,
      *      dataGroupHashValue     OCTET STRING }
    - * 
    + *
      * DataGroupNumber ::= INTEGER {
      *         dataGroup1    (1),
      *         dataGroup1    (2),
    @@ -33,15 +33,15 @@
      *         dataGroup1    (14),
      *         dataGroup1    (15),
      *         dataGroup1    (16) }
    - * 
    + *
      * 
    */ -public class DataGroupHash +public class DataGroupHash extends ASN1Object { - ASN1Integer dataGroupNumber; + ASN1Integer dataGroupNumber; ASN1OctetString dataGroupHashValue; - + public static DataGroupHash getInstance( Object obj) { @@ -55,8 +55,8 @@ else if (obj != null) } return null; - } - + } + private DataGroupHash(ASN1Sequence seq) { Enumeration e = seq.getObjects(); @@ -64,27 +64,27 @@ private DataGroupHash(ASN1Sequence seq) // dataGroupNumber dataGroupNumber = ASN1Integer.getInstance(e.nextElement()); // dataGroupHashValue - dataGroupHashValue = ASN1OctetString.getInstance(e.nextElement()); + dataGroupHashValue = ASN1OctetString.getInstance(e.nextElement()); } - + public DataGroupHash( - int dataGroupNumber, + int dataGroupNumber, ASN1OctetString dataGroupHashValue) { - this.dataGroupNumber = new ASN1Integer(dataGroupNumber); - this.dataGroupHashValue = dataGroupHashValue; - } + this.dataGroupNumber = ASN1Integer.valueOf(dataGroupNumber); + this.dataGroupHashValue = dataGroupHashValue; + } public int getDataGroupNumber() { return dataGroupNumber.intValueExact(); } - + public ASN1OctetString getDataGroupHashValue() { return dataGroupHashValue; - } - + } + public ASN1Primitive toASN1Primitive() { return new DERSequence(dataGroupNumber, dataGroupHashValue); diff --git a/util/src/main/java/org/bouncycastle/asn1/icao/LDSSecurityObject.java b/util/src/main/java/org/bouncycastle/asn1/icao/LDSSecurityObject.java index 89baf0a430..378229f7d7 100644 --- a/util/src/main/java/org/bouncycastle/asn1/icao/LDSSecurityObject.java +++ b/util/src/main/java/org/bouncycastle/asn1/icao/LDSSecurityObject.java @@ -31,7 +31,7 @@ public class LDSSecurityObject { public static final int ub_DataGroups = 16; - private ASN1Integer version = new ASN1Integer(0); + private ASN1Integer version = ASN1Integer.ZERO; private AlgorithmIdentifier digestAlgorithmIdentifier; private DataGroupHash[] datagroupHash; private LDSVersionInfo versionInfo; @@ -86,7 +86,7 @@ public LDSSecurityObject( AlgorithmIdentifier digestAlgorithmIdentifier, DataGroupHash[] datagroupHash) { - this.version = new ASN1Integer(0); + this.version = ASN1Integer.ZERO; this.digestAlgorithmIdentifier = digestAlgorithmIdentifier; this.datagroupHash = copy(datagroupHash); @@ -98,7 +98,7 @@ public LDSSecurityObject( DataGroupHash[] datagroupHash, LDSVersionInfo versionInfo) { - this.version = new ASN1Integer(1); + this.version = ASN1Integer.ONE; this.digestAlgorithmIdentifier = digestAlgorithmIdentifier; this.datagroupHash = copy(datagroupHash); this.versionInfo = versionInfo; diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java index 6b75fde631..d9369734d2 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/ISISMTTObjectIdentifiers.java @@ -103,7 +103,7 @@ public interface ISISMTTObjectIdentifiers *
    *

    * OID: 1.3.36.8.3.8 - * + * * @see org.bouncycastle.asn1.isismtt.x509.Restriction */ static final ASN1ObjectIdentifier id_isismtt_at_restriction = id_isismtt_at.branch("8"); @@ -129,7 +129,7 @@ public interface ISISMTTObjectIdentifiers * returned in this extension. *

    * OID: 1.3.36.8.3.10 - * + * * @see org.bouncycastle.asn1.isismtt.ocsp.RequestedCertificate */ static final ASN1ObjectIdentifier id_isismtt_at_requestedCertificate = id_isismtt_at.branch("10"); @@ -146,7 +146,7 @@ public interface ISISMTTObjectIdentifiers * in the directory and status information has become available. Currently, * accrediting authorities enforce that SigG-conforming OCSP servers include * this extension in the responses. - * + * *

          *    CertInDirSince ::= GeneralizedTime
          * 
    @@ -159,7 +159,7 @@ public interface ISISMTTObjectIdentifiers * Hash of a certificate in OCSP. *

    * OID: 1.3.36.8.3.13 - * + * * @see org.bouncycastle.asn1.isismtt.ocsp.CertHash */ static final ASN1ObjectIdentifier id_isismtt_at_certHash = id_isismtt_at.branch("13"); @@ -168,7 +168,7 @@ public interface ISISMTTObjectIdentifiers *

          *    NameAtBirth ::= DirectoryString(SIZE(1..64)
          * 
    - * + * * Used in * {@link org.bouncycastle.asn1.x509.SubjectDirectoryAttributes SubjectDirectoryAttributes} *

    @@ -180,13 +180,13 @@ public interface ISISMTTObjectIdentifiers * Some other information of non-restrictive nature regarding the usage of * this certificate. May be used as attribute in atribute certificate or as * extension in a certificate. - * + * *

          *    AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
          * 
    *

    * OID: 1.3.36.8.3.15 - * + * * @see org.bouncycastle.asn1.isismtt.x509.AdditionalInformationSyntax */ static final ASN1ObjectIdentifier id_isismtt_at_additionalInformation = id_isismtt_at.branch("15"); diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java index 9237e9833e..b50981675e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/ocsp/RequestedCertificate.java @@ -152,7 +152,7 @@ public byte[] getCertificateBytes() } return Arrays.clone(attributeCert); } - + /** * Produce an object suitable for an ASN1OutputStream. *

    diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdditionalInformationSyntax.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdditionalInformationSyntax.java index 454100a716..243253a35f 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdditionalInformationSyntax.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/AdditionalInformationSyntax.java @@ -7,7 +7,7 @@ /** * Some other information of non-restrictive nature regarding the usage of this * certificate. - * + * *

      *    AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
      * 
    diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/Admissions.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/Admissions.java index 3536638161..6099620de9 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/Admissions.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/Admissions.java @@ -27,7 +27,7 @@ * @see org.bouncycastle.asn1.isismtt.x509.ProfessionInfo * @see org.bouncycastle.asn1.isismtt.x509.NamingAuthority */ -public class Admissions +public class Admissions extends ASN1Object { @@ -168,7 +168,7 @@ public ProfessionInfo[] getProfessionInfos() public ASN1Primitive toASN1Primitive() { ASN1EncodableVector vec = new ASN1EncodableVector(3); - + if (admissionAuthority != null) { vec.add(new DERTaggedObject(true, 0, admissionAuthority)); diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java index f7eca1511b..a609f36398 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/DeclarationOfMajority.java @@ -8,7 +8,6 @@ import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -44,7 +43,7 @@ public class DeclarationOfMajority public DeclarationOfMajority(int notYoungerThan) { - declaration = new DERTaggedObject(false, 0, new ASN1Integer(notYoungerThan)); + declaration = new DERTaggedObject(false, 0, ASN1Integer.valueOf(notYoungerThan)); } public DeclarationOfMajority(boolean fullAge, String country) @@ -80,7 +79,7 @@ public static DeclarationOfMajority getInstance(Object obj) if (obj instanceof ASN1TaggedObject) { - return new DeclarationOfMajority(ASN1TaggedObject.getInstance(obj, BERTags.CONTEXT_SPECIFIC)); + return new DeclarationOfMajority(ASN1TaggedObject.getContextInstance(obj)); } throw new IllegalArgumentException("illegal object in getInstance: " diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/MonetaryLimit.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/MonetaryLimit.java index fd8529d119..a537c940d5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/MonetaryLimit.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/MonetaryLimit.java @@ -82,8 +82,8 @@ private MonetaryLimit(ASN1Sequence seq) public MonetaryLimit(String currency, int amount, int exponent) { this.currency = new DERPrintableString(currency, true); - this.amount = new ASN1Integer(amount); - this.exponent = new ASN1Integer(exponent); + this.amount = ASN1Integer.valueOf(amount); + this.exponent = ASN1Integer.valueOf(exponent); } public String getCurrency() diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/NamingAuthority.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/NamingAuthority.java index 470897738d..fa49b8454d 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/NamingAuthority.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/NamingAuthority.java @@ -19,9 +19,9 @@ /** * Names of authorities which are responsible for the administration of title * registers. - * + * *
    - *             NamingAuthority ::= SEQUENCE 
    + *             NamingAuthority ::= SEQUENCE
      *             {
      *               namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
      *               namingAuthorityUrl IA5String OPTIONAL,
    @@ -29,7 +29,7 @@
      *             }
      * 
    * @see org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax - * + * */ public class NamingAuthority extends ASN1Object diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java index 88d809e5aa..564833274e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProcurationSyntax.java @@ -9,7 +9,6 @@ import org.bouncycastle.asn1.ASN1PrintableString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; @@ -34,21 +33,21 @@ * stateOrProvincename, localityName, postalAddress) and - SubjectDirectoryName * attributes (title, dateOfBirth, placeOfBirth, gender, countryOfCitizenship, * countryOfResidence and NameAtBirth). - * + * *
      *               ProcurationSyntax ::= SEQUENCE {
      *                 country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
      *                 typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
    - *                 signingFor [3] EXPLICIT SigningFor 
    + *                 signingFor [3] EXPLICIT SigningFor
      *               }
    - *               
    - *               SigningFor ::= CHOICE 
    - *               { 
    + *
    + *               SigningFor ::= CHOICE
    + *               {
      *                 thirdPerson GeneralName,
    - *                 certRef IssuerSerial 
    + *                 certRef IssuerSerial
      *               }
      * 
    - * + * */ public class ProcurationSyntax extends ASN1Object @@ -105,7 +104,7 @@ private ProcurationSyntax(ASN1Sequence seq) while (e.hasMoreElements()) { - ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement(), BERTags.CONTEXT_SPECIFIC); + ASN1TaggedObject o = ASN1TaggedObject.getContextInstance(e.nextElement()); switch (o.getTagNo()) { case 1: diff --git a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProfessionInfo.java b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProfessionInfo.java index b987c5f4f2..811e60533c 100644 --- a/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProfessionInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/isismtt/x509/ProfessionInfo.java @@ -19,21 +19,21 @@ /** * Professions, specializations, disciplines, fields of activity, etc. - * + * *
    - *               ProfessionInfo ::= SEQUENCE 
    + *               ProfessionInfo ::= SEQUENCE
      *               {
      *                 namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
      *                 professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
      *                 professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
      *                 registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
    - *                 addProfessionInfo OCTET STRING OPTIONAL 
    + *                 addProfessionInfo OCTET STRING OPTIONAL
      *               }
      * 
    - * + * * @see org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax */ -public class ProfessionInfo +public class ProfessionInfo extends ASN1Object { diff --git a/util/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java b/util/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java index 1137eda46e..62caf1a568 100644 --- a/util/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java +++ b/util/src/main/java/org/bouncycastle/asn1/misc/CAST5CBCParameters.java @@ -35,7 +35,7 @@ public CAST5CBCParameters( int keyLength) { this.iv = new DEROctetString(Arrays.clone(iv)); - this.keyLength = new ASN1Integer(keyLength); + this.keyLength = ASN1Integer.valueOf(keyLength); } private CAST5CBCParameters( diff --git a/util/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java b/util/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java index 761b4c4aae..ed9f4a8023 100644 --- a/util/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java +++ b/util/src/main/java/org/bouncycastle/asn1/misc/NetscapeCertType.java @@ -20,7 +20,7 @@ public class NetscapeCertType extends DERBitString { - public static final int sslClient = (1 << 7); + public static final int sslClient = (1 << 7); public static final int sslServer = (1 << 6); public static final int smime = (1 << 5); public static final int objectSigning = (1 << 4); @@ -31,7 +31,7 @@ public class NetscapeCertType /** * Basic constructor. - * + * * @param usage - the bitwise OR of the Key Usage flags giving the * allowed uses for the key. * e.g. (X509NetscapeCertType.sslCA | X509NetscapeCertType.smimeCA) diff --git a/util/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java b/util/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java index 6b11b7bcb5..42062029d3 100644 --- a/util/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java +++ b/util/src/main/java/org/bouncycastle/asn1/misc/ScryptParams.java @@ -43,7 +43,7 @@ public ScryptParams(byte[] salt, int costParameter, int blockSize, int paralleli { this(salt, BigInteger.valueOf(costParameter), BigInteger.valueOf(blockSize), BigInteger.valueOf(parallelizationParameter), BigInteger.valueOf(keyLength)); } - + /** * Base constructor. * diff --git a/util/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java b/util/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java index c169c1692d..7b6c3ce86e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java +++ b/util/src/main/java/org/bouncycastle/asn1/oiw/OIWObjectIdentifiers.java @@ -5,7 +5,7 @@ /** * OIW organization's OIDs: *

    - * id-SHA1 OBJECT IDENTIFIER ::= + * id-SHA1 OBJECT IDENTIFIER ::= * {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */ public interface OIWObjectIdentifiers @@ -16,7 +16,7 @@ public interface OIWObjectIdentifiers static final ASN1ObjectIdentifier md5WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.3"); /** OID: 1.3.14.3.2.4 */ static final ASN1ObjectIdentifier md4WithRSAEncryption = new ASN1ObjectIdentifier("1.3.14.3.2.4"); - + /** OID: 1.3.14.3.2.6 */ static final ASN1ObjectIdentifier desECB = new ASN1ObjectIdentifier("1.3.14.3.2.6"); /** OID: 1.3.14.3.2.7 */ @@ -28,7 +28,7 @@ public interface OIWObjectIdentifiers /** OID: 1.3.14.3.2.17 */ static final ASN1ObjectIdentifier desEDE = new ASN1ObjectIdentifier("1.3.14.3.2.17"); - + /** OID: 1.3.14.3.2.26 */ static final ASN1ObjectIdentifier idSHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26"); @@ -37,10 +37,10 @@ public interface OIWObjectIdentifiers /** OID: 1.3.14.3.2.29 */ static final ASN1ObjectIdentifier sha1WithRSA = new ASN1ObjectIdentifier("1.3.14.3.2.29"); - + /** *

    -     * ElGamal Algorithm OBJECT IDENTIFIER ::=    
    +     * ElGamal Algorithm OBJECT IDENTIFIER ::=
          *   {iso(1) identified-organization(3) oiw(14) dirservsig(7) algorithm(2) encryption(1) 1 }
          * 
    * OID: 1.3.14.7.2.1.1 diff --git a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilities.java b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilities.java index 9c7fba4718..aaa28fe67e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilities.java +++ b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilities.java @@ -35,7 +35,7 @@ public class SMIMECapabilities public static final ASN1ObjectIdentifier dES_CBC = new ASN1ObjectIdentifier("1.3.14.3.2.7"); public static final ASN1ObjectIdentifier dES_EDE3_CBC = PKCSObjectIdentifiers.des_EDE3_CBC; public static final ASN1ObjectIdentifier rC2_CBC = PKCSObjectIdentifiers.RC2_CBC; - + private ASN1Sequence capabilities; /** @@ -51,7 +51,7 @@ public static SMIMECapabilities getInstance( { return (SMIMECapabilities)o; } - + if (o instanceof ASN1Sequence) { return new SMIMECapabilities((ASN1Sequence)o); @@ -65,7 +65,7 @@ public static SMIMECapabilities getInstance( throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } - + public SMIMECapabilities( ASN1Sequence seq) { @@ -108,7 +108,7 @@ public Vector getCapabilities( return list; } - /** + /** * Produce an object suitable for an ASN1OutputStream. *
          * SMIMECapabilities ::= SEQUENCE OF SMIMECapability
    diff --git a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapability.java b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapability.java
    index 0b762af1d4..9df494f9d3 100644
    --- a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapability.java
    +++ b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapability.java
    @@ -29,7 +29,7 @@ public class SMIMECapability
         public static final ASN1ObjectIdentifier aES128_CBC = NISTObjectIdentifiers.id_aes128_CBC;
         public static final ASN1ObjectIdentifier aES192_CBC = NISTObjectIdentifiers.id_aes192_CBC;
         public static final ASN1ObjectIdentifier aES256_CBC = NISTObjectIdentifiers.id_aes256_CBC;
    -    
    +
         private ASN1ObjectIdentifier capabilityID;
         private ASN1Encodable        parameters;
     
    @@ -51,7 +51,7 @@ public SMIMECapability(
             this.capabilityID = capabilityID;
             this.parameters = parameters;
         }
    -    
    +
         public static SMIMECapability getInstance(
             Object obj)
         {
    @@ -59,14 +59,14 @@ public static SMIMECapability getInstance(
             {
                 return (SMIMECapability)obj;
             }
    -        
    +
             if (obj instanceof ASN1Sequence)
             {
                 return new SMIMECapability((ASN1Sequence)obj);
             }
    -        
    +
             throw new IllegalArgumentException("Invalid SMIMECapability");
    -    } 
    +    }
     
         public ASN1ObjectIdentifier getCapabilityID()
         {
    @@ -80,10 +80,10 @@ public ASN1Encodable getParameters()
     
         /**
          * Produce an object suitable for an ASN1OutputStream.
    -     * 
     
    +     * 
          * SMIMECapability ::= SEQUENCE {
          *     capabilityID OBJECT IDENTIFIER,
    -     *     parameters ANY DEFINED BY capabilityID OPTIONAL 
    +     *     parameters ANY DEFINED BY capabilityID OPTIONAL
          * }
          * 
    */ @@ -92,12 +92,12 @@ public ASN1Primitive toASN1Primitive() ASN1EncodableVector v = new ASN1EncodableVector(2); v.add(capabilityID); - + if (parameters != null) { v.add(parameters); } - + return new DERSequence(v); } } diff --git a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilityVector.java b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilityVector.java index 673a745e4e..b15889c430 100644 --- a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilityVector.java +++ b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMECapabilityVector.java @@ -23,7 +23,7 @@ public void addCapability( ASN1ObjectIdentifier capability, int value) { - capabilities.add(new DERSequence(capability, new ASN1Integer(value))); + capabilities.add(new DERSequence(capability, ASN1Integer.valueOf(value))); } public void addCapability( diff --git a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.java b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.java index 1e5b5396c6..9ff8ae8ff2 100644 --- a/util/src/main/java/org/bouncycastle/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.java +++ b/util/src/main/java/org/bouncycastle/asn1/smime/SMIMEEncryptionKeyPreferenceAttribute.java @@ -26,15 +26,15 @@ public SMIMEEncryptionKeyPreferenceAttribute( super(SMIMEAttributes.encrypKeyPref, new DERSet(new DERTaggedObject(false, 0, issAndSer))); } - + public SMIMEEncryptionKeyPreferenceAttribute( RecipientKeyIdentifier rKeyId) { - super(SMIMEAttributes.encrypKeyPref, + super(SMIMEAttributes.encrypKeyPref, new DERSet(new DERTaggedObject(false, 1, rKeyId))); } - + /** * @param sKeyId the subjectKeyIdentifier value (normally the X.509 one) */ diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/Accuracy.java b/util/src/main/java/org/bouncycastle/asn1/tsp/Accuracy.java index 254fa78731..b8db9ef54f 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/Accuracy.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/Accuracy.java @@ -1,5 +1,6 @@ package org.bouncycastle.asn1.tsp; +import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; @@ -9,111 +10,111 @@ import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; - public class Accuracy extends ASN1Object { - ASN1Integer seconds; - - ASN1Integer millis; - - ASN1Integer micros; - - // constantes protected static final int MIN_MILLIS = 1; - protected static final int MAX_MILLIS = 999; - protected static final int MIN_MICROS = 1; - protected static final int MAX_MICROS = 999; - protected Accuracy() - { - } - - public Accuracy( - ASN1Integer seconds, - ASN1Integer millis, - ASN1Integer micros) + public static Accuracy getInstance(Object obj) { - if (null != millis) + if (obj instanceof Accuracy) { - int millisValue = millis.intValueExact(); - if (millisValue < MIN_MILLIS || millisValue > MAX_MILLIS) - { - throw new IllegalArgumentException("Invalid millis field : not in (1..999)"); - } + return (Accuracy)obj; } - if (null != micros) + if (obj != null) { - int microsValue = micros.intValueExact(); - if (microsValue < MIN_MICROS || microsValue > MAX_MICROS) - { - throw new IllegalArgumentException("Invalid micros field : not in (1..999)"); - } + return new Accuracy(ASN1Sequence.getInstance(obj)); } + return null; + } - this.seconds = seconds; - this.millis = millis; - this.micros = micros; + public static Accuracy getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new Accuracy(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); } - private Accuracy(ASN1Sequence seq) + public static Accuracy getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new Accuracy(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); + } + + private final ASN1Integer seconds; + private final ASN1Integer millis; + private final ASN1Integer micros; + + /** @deprecated Will be removed */ + protected Accuracy() { seconds = null; millis = null; micros = null; + } + + private Accuracy(ASN1Sequence seq) + { + int count = seq.size(), pos = 0; + if (count < 0 || count > 3) + { + throw new IllegalArgumentException("Bad sequence size: " + count); + } - for (int i = 0; i < seq.size(); i++) + // seconds INTEGER OPTIONAL + ASN1Integer seconds = null; + if (pos < count) { - // seconds - if (seq.getObjectAt(i) instanceof ASN1Integer) + ASN1Encodable element = seq.getObjectAt(pos); + if (element instanceof ASN1Integer) { - seconds = (ASN1Integer) seq.getObjectAt(i); + pos++; + seconds = (ASN1Integer)element; } - else if (seq.getObjectAt(i) instanceof ASN1TaggedObject) + } + this.seconds = seconds; + + // millis [0] INTEGER (1..999) OPTIONAL + ASN1Integer millis = null; + if (pos < count) + { + ASN1TaggedObject tag0 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 0); + if (tag0 != null) { - ASN1TaggedObject extra = (ASN1TaggedObject)seq.getObjectAt(i); - - switch (extra.getTagNo()) - { - case 0: - millis = ASN1Integer.getInstance(extra, false); - int millisValue = millis.intValueExact(); - if (millisValue < MIN_MILLIS || millisValue > MAX_MILLIS) - { - throw new IllegalArgumentException("Invalid millis field : not in (1..999)"); - } - break; - case 1: - micros = ASN1Integer.getInstance(extra, false); - int microsValue = micros.intValueExact(); - if (microsValue < MIN_MICROS || microsValue > MAX_MICROS) - { - throw new IllegalArgumentException("Invalid micros field : not in (1..999)"); - } - break; - default: - throw new IllegalArgumentException("Invalid tag number"); - } + pos++; + millis = ASN1Integer.getInstance(tag0, false); } } - } + this.millis = millis; - public static Accuracy getInstance(Object o) - { - if (o instanceof Accuracy) + // micros [1] INTEGER (1..999) OPTIONAL + ASN1Integer micros = null; + if (pos < count) { - return (Accuracy) o; + ASN1TaggedObject tag1 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 1); + if (tag1 != null) + { + pos++; + micros = ASN1Integer.getInstance(tag1, false); + } } + this.micros = micros; - if (o != null) + if (pos != count) { - return new Accuracy(ASN1Sequence.getInstance(o)); + throw new IllegalArgumentException("Unexpected elements in sequence"); } - return null; + validate(); + } + + public Accuracy(ASN1Integer seconds, ASN1Integer millis, ASN1Integer micros) + { + this.seconds = seconds; + this.millis = millis; + this.micros = micros; + + validate(); } public ASN1Integer getSeconds() @@ -143,17 +144,17 @@ public ASN1Integer getMicros() public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(3); - + if (seconds != null) { v.add(seconds); } - + if (millis != null) { v.add(new DERTaggedObject(false, 0, millis)); } - + if (micros != null) { v.add(new DERTaggedObject(false, 1, micros)); @@ -161,4 +162,24 @@ public ASN1Primitive toASN1Primitive() return new DERSequence(v); } + + private void validate() + { + if (millis != null) + { + int millisValue = millis.intValueExact(); + if (millisValue < MIN_MILLIS || millisValue > MAX_MILLIS) + { + throw new IllegalArgumentException("Invalid millis field : not in (1..999)"); + } + } + if (micros != null) + { + int microsValue = micros.intValueExact(); + if (microsValue < MIN_MICROS || microsValue > MAX_MICROS) + { + throw new IllegalArgumentException("Invalid micros field : not in (1..999)"); + } + } + } } diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java index 90e404e266..929553bfb5 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/ArchiveTimeStamp.java @@ -34,11 +34,6 @@ public class ArchiveTimeStamp extends ASN1Object { - private final AlgorithmIdentifier digestAlgorithm; - private final Attributes attributes; - private final ASN1Sequence reducedHashTree; - private final ContentInfo timeStamp; - /** * Return an ArchiveTimestamp from the given object. * @@ -46,7 +41,7 @@ public class ArchiveTimeStamp * @return an ArchiveTimestamp instance, or null. * @throws IllegalArgumentException if the object cannot be converted. */ - public static ArchiveTimeStamp getInstance(final Object obj) + public static ArchiveTimeStamp getInstance(Object obj) { if (obj instanceof ArchiveTimeStamp) { @@ -60,6 +55,21 @@ else if (obj != null) return null; } + public static ArchiveTimeStamp getInstance(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new ArchiveTimeStamp(ASN1Sequence.getInstance(taggedObject, declaredExplicit)); + } + + public static ArchiveTimeStamp getTagged(ASN1TaggedObject taggedObject, boolean declaredExplicit) + { + return new ArchiveTimeStamp(ASN1Sequence.getTagged(taggedObject, declaredExplicit)); + } + + private final AlgorithmIdentifier digestAlgorithm; + private final Attributes attributes; + private final ASN1Sequence reducedHashTree; + private final ContentInfo timeStamp; + public ArchiveTimeStamp( AlgorithmIdentifier digestAlgorithm, PartialHashtree[] reducedHashTree, @@ -80,59 +90,71 @@ public ArchiveTimeStamp( PartialHashtree[] reducedHashTree, ContentInfo timeStamp) { - this.digestAlgorithm = digestAlgorithm; - this.attributes = attributes; - if (reducedHashTree != null) - { - this.reducedHashTree = new DERSequence(reducedHashTree); - } - else + if (timeStamp == null) { - this.reducedHashTree = null; + throw new NullPointerException("'timeStamp' cannot be null"); } + + this.digestAlgorithm = digestAlgorithm; + this.attributes = attributes; + this.reducedHashTree = DERSequence.fromElementsOptional(reducedHashTree); this.timeStamp = timeStamp; } - private ArchiveTimeStamp(final ASN1Sequence sequence) + private ArchiveTimeStamp(ASN1Sequence seq) { - if (sequence.size() < 1 || sequence.size() > 4) + int count = seq.size(), pos = 0; + if (count < 1 || count > 4) + { + throw new IllegalArgumentException("Bad sequence size: " + count); + } + + // digestAlgorithm [Ø] AlgorithmIdentifier OPTIONAL + AlgorithmIdentifier digestAlgorithm = null; + if (pos < count) { - throw new IllegalArgumentException("wrong sequence size in constructor: " + sequence.size()); + ASN1TaggedObject tag0 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 0); + if (tag0 != null) + { + pos++; + digestAlgorithm = AlgorithmIdentifier.getTagged(tag0, false); + } } + this.digestAlgorithm = digestAlgorithm; - AlgorithmIdentifier digAlg = null; - Attributes attrs = null; - ASN1Sequence rHashTree = null; - for (int i = 0; i < sequence.size() - 1; i++) + // attributes [1] Attributes OPTIONAL + Attributes attributes = null; + if (pos < count) { - Object obj = sequence.getObjectAt(i); + ASN1TaggedObject tag1 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 1); + if (tag1 != null) + { + pos++; + attributes = Attributes.getTagged(tag1, false); + } + } + this.attributes = attributes; - if (obj instanceof ASN1TaggedObject) + // reducedHashtree [2] SEQUENCE OF PartialHashtree OPTIONAL + ASN1Sequence reducedHashTree = null; + if (pos < count) + { + ASN1TaggedObject tag2 = ASN1TaggedObject.getContextOptional(seq.getObjectAt(pos), 2); + if (tag2 != null) { - ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(obj); - - switch (taggedObject.getTagNo()) - { - case 0: - digAlg = AlgorithmIdentifier.getInstance(taggedObject, false); - break; - case 1: - attrs = Attributes.getInstance(taggedObject, false); - break; - case 2: - rHashTree = ASN1Sequence.getInstance(taggedObject, false); - break; - default: - throw new IllegalArgumentException("invalid tag no in constructor: " - + taggedObject.getTagNo()); - } + pos++; + reducedHashTree = ASN1Sequence.getInstance(tag2, false); } } + this.reducedHashTree = reducedHashTree; + + // timeStamp ContentInfo + timeStamp = ContentInfo.getInstance(seq.getObjectAt(pos++)); - digestAlgorithm = digAlg; - attributes = attrs; - reducedHashTree = rHashTree; - timeStamp = ContentInfo.getInstance(sequence.getObjectAt(sequence.size() - 1)); + if (pos != count) + { + throw new IllegalArgumentException("Unexpected elements in sequence"); + } } public AlgorithmIdentifier getDigestAlgorithmIdentifier() @@ -141,10 +163,8 @@ public AlgorithmIdentifier getDigestAlgorithmIdentifier() { return digestAlgorithm; } - else - { - return getTimeStampInfo().getMessageImprint().getHashAlgorithm(); - } + + return getTimeStampInfo().getMessageImprint().getHashAlgorithm(); } public byte[] getTimeStampDigestValue() @@ -154,25 +174,22 @@ public byte[] getTimeStampDigestValue() private TSTInfo getTimeStampInfo() { - if (timeStamp.getContentType().equals(CMSObjectIdentifiers.signedData)) + if (!CMSObjectIdentifiers.signedData.equals(timeStamp.getContentType())) { - SignedData tsData = SignedData.getInstance(timeStamp.getContent()); - if (tsData.getEncapContentInfo().getContentType().equals(PKCSObjectIdentifiers.id_ct_TSTInfo)) - { - TSTInfo tstData = TSTInfo.getInstance( - ASN1OctetString.getInstance(tsData.getEncapContentInfo().getContent()).getOctets()); - - return tstData; - } - else - { - throw new IllegalStateException("cannot parse time stamp"); - } + throw new IllegalStateException("cannot identify algorithm identifier for digest"); } - else + + SignedData tsData = SignedData.getInstance(timeStamp.getContent()); + ContentInfo encapContentInfo = tsData.getEncapContentInfo(); + + if (!PKCSObjectIdentifiers.id_ct_TSTInfo.equals(encapContentInfo.getContentType())) { - throw new IllegalStateException("cannot identify algorithm identifier for digest"); + throw new IllegalStateException("cannot parse time stamp"); } + + ASN1OctetString encapContent = ASN1OctetString.getInstance(encapContentInfo.getContent()); + + return TSTInfo.getInstance(encapContent.getOctets()); } /** @@ -194,10 +211,10 @@ public PartialHashtree getHashTreeLeaf() { if (reducedHashTree == null) { - return null; + return null; } - return PartialHashtree.getInstance(reducedHashTree.getObjectAt(0)); + return PartialHashtree.getInstance(reducedHashTree.getObjectAt(0)); } public PartialHashtree[] getReducedHashTree() @@ -221,7 +238,7 @@ public ContentInfo getTimeStamp() { return timeStamp; } - + public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(4); @@ -245,4 +262,4 @@ public ASN1Primitive toASN1Primitive() return new DERSequence(v); } -} \ No newline at end of file +} diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/EvidenceRecord.java b/util/src/main/java/org/bouncycastle/asn1/tsp/EvidenceRecord.java index fdf046e5d5..5494aa0547 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/EvidenceRecord.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/EvidenceRecord.java @@ -40,7 +40,7 @@ public class EvidenceRecord */ private static final ASN1ObjectIdentifier OID = new ASN1ObjectIdentifier("1.3.6.1.5.5.11.0.2.1"); - private ASN1Integer version = new ASN1Integer(1); + private ASN1Integer version = ASN1Integer.ONE; private ASN1Sequence digestAlgorithms; private CryptoInfos cryptoInfos; private EncryptionInfo encryptionInfo; @@ -123,7 +123,7 @@ private EvidenceRecord( /** * Build a basic evidence record from an initial * ArchiveTimeStamp. - * + * * @param cryptoInfos * @param encryptionInfo * @param archiveTimeStamp @@ -226,7 +226,7 @@ public EvidenceRecord addArchiveTimeStamp(final ArchiveTimeStamp ats, final bool if (newChain) { ArchiveTimeStampChain chain = new ArchiveTimeStampChain(ats); - + return new EvidenceRecord(this, archiveTimeStampSequence.append(chain), ats); } else diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/MessageImprint.java b/util/src/main/java/org/bouncycastle/asn1/tsp/MessageImprint.java index 56b9e09c68..62daaf2acd 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/MessageImprint.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/MessageImprint.java @@ -14,10 +14,10 @@ public class MessageImprint { AlgorithmIdentifier hashAlgorithm; byte[] hashedMessage; - + /** * Return an instance of MessageImprint, or null, based on o. - * + * * @param o the object to be converted. * @return a MessageImprint object. */ @@ -35,7 +35,7 @@ public static MessageImprint getInstance(Object o) return null; } - + private MessageImprint( ASN1Sequence seq) { @@ -49,7 +49,7 @@ private MessageImprint( throw new IllegalArgumentException("sequence has wrong number of elements"); } } - + public MessageImprint( AlgorithmIdentifier hashAlgorithm, byte[] hashedMessage) @@ -57,7 +57,7 @@ public MessageImprint( this.hashAlgorithm = hashAlgorithm; this.hashedMessage = Arrays.clone(hashedMessage); } - + public AlgorithmIdentifier getHashAlgorithm() { return hashAlgorithm; diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/TSTInfo.java b/util/src/main/java/org/bouncycastle/asn1/tsp/TSTInfo.java index 51314d69fb..00e569d191 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/TSTInfo.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/TSTInfo.java @@ -65,7 +65,7 @@ private TSTInfo(ASN1Sequence seq) // default for ordering ordering = ASN1Boolean.getInstance(false); - + while (e.hasMoreElements()) { ASN1Object o = (ASN1Object) e.nextElement(); @@ -107,7 +107,7 @@ public TSTInfo(ASN1ObjectIdentifier tsaPolicyId, MessageImprint messageImprint, Accuracy accuracy, ASN1Boolean ordering, ASN1Integer nonce, GeneralName tsa, Extensions extensions) { - version = new ASN1Integer(1); + version = ASN1Integer.ONE; this.tsaPolicyId = tsaPolicyId; this.messageImprint = messageImprint; this.serialNumber = serialNumber; @@ -172,7 +172,7 @@ public Extensions getExtensions() /** *
    -     * 
    +     *
          *     TSTInfo ::= SEQUENCE  {
          *        version                      INTEGER  { v1(1) },
          *        policy                       TSAPolicyId,
    @@ -190,7 +190,7 @@ public Extensions getExtensions()
          *          -- in TimeStampReq.  In that case it MUST have the same value.
          *        tsa                          [0] GeneralName          OPTIONAL,
          *        extensions                   [1] IMPLICIT Extensions   OPTIONAL  }
    -     * 
    +     *
          * 
    */ public ASN1Primitive toASN1Primitive() @@ -207,22 +207,22 @@ public ASN1Primitive toASN1Primitive() { seq.add(accuracy); } - + if (ordering != null && ordering.isTrue()) { seq.add(ordering); } - + if (nonce != null) { seq.add(nonce); } - + if (tsa != null) { seq.add(new DERTaggedObject(true, 0, tsa)); } - + if (extensions != null) { seq.add(new DERTaggedObject(false, 1, extensions)); diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampReq.java b/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampReq.java index 4165abb720..0c53fac43e 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampReq.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampReq.java @@ -110,7 +110,7 @@ public TimeStampReq( Extensions extensions) { // default - version = new ASN1Integer(1); + version = ASN1Integer.ONE; this.messageImprint = messageImprint; this.tsaPolicy = tsaPolicy; @@ -170,25 +170,25 @@ public Extensions getExtensions() public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(6); - + v.add(version); v.add(messageImprint); - + if (tsaPolicy != null) { v.add(tsaPolicy); } - + if (nonce != null) { v.add(nonce); } - + if (certReq != null && certReq.isTrue()) { v.add(certReq); } - + if (extensions != null) { v.add(new DERTaggedObject(false, 0, extensions)); diff --git a/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampResp.java b/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampResp.java index bdfc47cb94..4bdf6a6c9c 100644 --- a/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampResp.java +++ b/util/src/main/java/org/bouncycastle/asn1/tsp/TimeStampResp.java @@ -72,7 +72,7 @@ public ContentInfo getTimeStampToken() public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(2); - + v.add(pkiStatusInfo); if (timeStampToken != null) { diff --git a/util/src/main/java/org/bouncycastle/oer/OERDefinition.java b/util/src/main/java/org/bouncycastle/oer/OERDefinition.java index fee99d1020..1f87cdf7f6 100644 --- a/util/src/main/java/org/bouncycastle/oer/OERDefinition.java +++ b/util/src/main/java/org/bouncycastle/oer/OERDefinition.java @@ -40,7 +40,7 @@ public static Builder integer() public static Builder integer(long val) { - return new Builder(BaseType.INT).defaultValue(new ASN1Integer(val)); + return new Builder(BaseType.INT).defaultValue(ASN1Integer.valueOf(val)); } public static Builder bitString(long len) diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java index b5659bbed2..7cca29a16e 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlCommand.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -57,7 +56,7 @@ public static CtlCommand getInstance(Object o) if (o != null) { - return new CtlCommand(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new CtlCommand(ASN1TaggedObject.getContextInstance(o)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java index 11c987ac2a..28d4167633 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlDelete.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashedId8; @@ -67,7 +66,7 @@ public static CtlDelete getInstance(Object o) if (o != null) { - return new CtlDelete(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new CtlDelete(ASN1TaggedObject.getContextInstance(o)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java index cf8b2aaed5..7e9bc279df 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/CtlEntry.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -74,7 +73,7 @@ public static CtlEntry getInstance(Object o) if (o != null) { - return new CtlEntry(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new CtlEntry(ASN1TaggedObject.getContextInstance(o)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java index 441f467e9d..d64752d7eb 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/EtsiTs102941DataContent.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -120,7 +119,7 @@ public static EtsiTs102941DataContent getInstance(Object o) if (o != null) { - return new EtsiTs102941DataContent(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new EtsiTs102941DataContent(ASN1TaggedObject.getContextInstance(o)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/CertificateFormat.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/CertificateFormat.java index 416d396292..a9a93c9744 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/CertificateFormat.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/CertificateFormat.java @@ -53,6 +53,6 @@ public static CertificateFormat getInstance(Object o) public ASN1Primitive toASN1Primitive() { - return new ASN1Integer(format); + return ASN1Integer.valueOf(format); } } diff --git a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java index e875b26a49..e495108feb 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java +++ b/util/src/main/java/org/bouncycastle/oer/its/etsi102941/basetypes/EcSignature.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.etsi103097.EtsiTs103097DataEncrypted; import org.bouncycastle.oer.its.etsi103097.EtsiTs103097DataSignedExternalPayload; @@ -59,7 +58,7 @@ public static EcSignature getInstance(Object o) } if (o != null) { - return new EcSignature(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new EcSignature(ASN1TaggedObject.getContextInstance(o)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/AesCcmCiphertext.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/AesCcmCiphertext.java index 4af39768c7..156c77a7e3 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/AesCcmCiphertext.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/AesCcmCiphertext.java @@ -92,7 +92,7 @@ public Builder setNonce(byte[] nonce) { return setNonce(new DEROctetString(Arrays.clone(nonce))); } - + public Builder setCcmCiphertext(Opaque opaque) { this.opaque = opaque; @@ -109,4 +109,4 @@ public AesCcmCiphertext createAesCcmCiphertext() return new AesCcmCiphertext(nonce, opaque); } } -} \ No newline at end of file +} diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java index c914942850..897dadde84 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/CertificateId.java @@ -7,7 +7,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; @@ -98,7 +97,7 @@ public static CertificateId getInstance(Object o) if (o != null) { - return new CertificateId(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new CertificateId(ASN1TaggedObject.getContextInstance(o)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java index 3242efed94..c666c92439 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/EncryptedDataEncryptionKey.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EciesP256EncryptedKey; @@ -56,7 +55,7 @@ public static EncryptedDataEncryptionKey getInstance(Object o) if (o != null) { - return new EncryptedDataEncryptionKey(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new EncryptedDataEncryptionKey(ASN1TaggedObject.getContextInstance(o)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java index 4c108e1b24..6ab6ded38c 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HashedData.java @@ -6,7 +6,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.Arrays; @@ -93,7 +92,7 @@ public static HashedData getInstance(Object o) if (o != null) { - return new HashedData(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC)); + return new HashedData(ASN1TaggedObject.getContextInstance(o)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HeaderInfo.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HeaderInfo.java index 2ed30c2f79..49e77c0012 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HeaderInfo.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/HeaderInfo.java @@ -308,4 +308,4 @@ public HeaderInfo createHeaderInfo() } -} \ No newline at end of file +} diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java index 3e21cecc41..401cfb498f 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/Ieee1609Dot2Content.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.util.Arrays; @@ -103,7 +102,7 @@ public static Ieee1609Dot2Content getInstance(Object src) if (src != null) { - return new Ieee1609Dot2Content(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC)); + return new Ieee1609Dot2Content(ASN1TaggedObject.getContextInstance(src)); } return null; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java index e30df5f265..3f28112d44 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/IssuerIdentifier.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashAlgorithm; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashedId8; @@ -83,7 +82,7 @@ public static IssuerIdentifier getInstance(Object choice) if (choice != null) { - return new IssuerIdentifier(ASN1TaggedObject.getInstance(choice, BERTags.CONTEXT_SPECIFIC)); + return new IssuerIdentifier(ASN1TaggedObject.getContextInstance(choice)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/PsidGroupPermissions.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/PsidGroupPermissions.java index 2cb8843c12..8fdefcdbdf 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/PsidGroupPermissions.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/PsidGroupPermissions.java @@ -123,7 +123,7 @@ public Builder setMinChainLength(BigInteger minChainLength) public Builder setMinChainLength(long minChainLength) { - this.minChainLength = new ASN1Integer(minChainLength); + this.minChainLength = ASN1Integer.valueOf(minChainLength); return this; } @@ -147,7 +147,7 @@ public Builder setChainLengthRange(BigInteger chainLengthRange) public Builder setChainLengthRange(long chainLengthRange) { - this.chainLengthRange = new ASN1Integer(chainLengthRange); + this.chainLengthRange = ASN1Integer.valueOf(chainLengthRange); return this; } diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java index eb11b5969b..f606e48c12 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/RecipientInfo.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERTaggedObject; /** @@ -70,7 +69,7 @@ public static RecipientInfo getInstance(Object object) if (object != null) { - return new RecipientInfo(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC)); + return new RecipientInfo(ASN1TaggedObject.getContextInstance(object)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SequenceOfPsidGroupPermissions.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SequenceOfPsidGroupPermissions.java index c0ce16c3b1..4e687c999e 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SequenceOfPsidGroupPermissions.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SequenceOfPsidGroupPermissions.java @@ -90,4 +90,4 @@ public SequenceOfPsidGroupPermissions createSequenceOfPsidGroupPermissions() } } -} \ No newline at end of file +} diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignedData.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignedData.java index 8714fcead4..73761417d0 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignedData.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignedData.java @@ -131,4 +131,4 @@ public SignedData createSignedData() } -} \ No newline at end of file +} diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java index 8ae0765b34..2df9f39043 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SignerIdentifier.java @@ -5,7 +5,6 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.HashedId8; @@ -121,7 +120,7 @@ public static SignerIdentifier getInstance(Object src) if (src != null) { - return new SignerIdentifier(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC)); + return new SignerIdentifier(ASN1TaggedObject.getContextInstance(src)); } return null; diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java index 4752294792..3fe976c72f 100644 --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SubjectPermissions.java @@ -6,12 +6,10 @@ import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.oer.its.ieee1609dot2.basetypes.SequenceOfPsidSspRange; - /** *
      *     SubjectPermissions ::= CHOICE {
    @@ -77,7 +75,7 @@ public static SubjectPermissions getInstance(Object src)
     
             if (src != null)
             {
    -            return new SubjectPermissions(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC));
    +            return new SubjectPermissions(ASN1TaggedObject.getContextInstance(src));
             }
             return null;
         }
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java
    index e568675684..9ed7ed22db 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/SymmetricCiphertext.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
     /**
    @@ -59,7 +58,7 @@ public static SymmetricCiphertext getInstance(Object o)
     
             if (o != null)
             {
    -            return new SymmetricCiphertext(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new SymmetricCiphertext(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/ToBeSignedData.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/ToBeSignedData.java
    index c4c52b7632..fc4ef8324f 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/ToBeSignedData.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/ToBeSignedData.java
    @@ -96,4 +96,4 @@ public ToBeSignedData createToBeSignedData()
             }
         }
     
    -}
    \ No newline at end of file
    +}
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java
    index 1550334920..dae186254a 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/VerificationKeyIndicator.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccP256CurvePoint;
     import org.bouncycastle.oer.its.ieee1609dot2.basetypes.PublicVerificationKey;
    @@ -74,7 +73,7 @@ public static VerificationKeyIndicator getInstance(Object src)
     
             if (src != null)
             {
    -            return new VerificationKeyIndicator(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC));
    +            return new VerificationKeyIndicator(ASN1TaggedObject.getContextInstance(src));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java
    index 75e0921b94..f7a09476f2 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/BasePublicEncryptionKey.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
     /**
    @@ -54,7 +53,7 @@ public static BasePublicEncryptionKey getInstance(Object objectAt)
     
             if (objectAt != null)
             {
    -            return new BasePublicEncryptionKey(ASN1TaggedObject.getInstance(objectAt, BERTags.CONTEXT_SPECIFIC));
    +            return new BasePublicEncryptionKey(ASN1TaggedObject.getContextInstance(objectAt));
             }
             return null;
         }
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/CircularRegion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/CircularRegion.java
    index 189b9f9352..dd030e9b3c 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/CircularRegion.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/CircularRegion.java
    @@ -95,4 +95,4 @@ public CircularRegion createCircularRegion()
                 return new CircularRegion(center, radius);
             }
         }
    -}
    \ No newline at end of file
    +}
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java
    index f619199e6c..3e2a56efa1 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Duration.java
    @@ -4,7 +4,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
     /**
    @@ -76,7 +75,7 @@ public static Duration getInstance(Object o)
     
             if (o != null)
             {
    -            return new Duration(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new Duration(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java
    index fa6e4205e4..63ec117d94 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP256CurvePoint.java
    @@ -8,7 +8,6 @@
     import org.bouncycastle.asn1.ASN1OctetString;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERNull;
     import org.bouncycastle.asn1.DEROctetString;
     import org.bouncycastle.asn1.DERTaggedObject;
    @@ -178,7 +177,7 @@ public static EccP256CurvePoint getInstance(Object object)
     
             if (object != null)
             {
    -            return new EccP256CurvePoint(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC));
    +            return new EccP256CurvePoint(ASN1TaggedObject.getContextInstance(object));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java
    index 9e50905198..272041382c 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EccP384CurvePoint.java
    @@ -7,7 +7,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERNull;
     import org.bouncycastle.asn1.DEROctetString;
     import org.bouncycastle.asn1.DERTaggedObject;
    @@ -76,7 +75,7 @@ public static EccP384CurvePoint getInstance(Object object)
     
             if (object != null)
             {
    -            return new EccP384CurvePoint(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC));
    +            return new EccP384CurvePoint(ASN1TaggedObject.getContextInstance(object));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java
    index 630f1660ca..aa68ddee15 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/EncryptionKey.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
     /**
    @@ -34,7 +33,7 @@ public static EncryptionKey getInstance(Object o)
             }
             if (o != null)
             {
    -            return new EncryptionKey(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new EncryptionKey(ASN1TaggedObject.getContextInstance(o));
             }
             return null;
         }
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java
    index 0cb46dacd6..6fa1f8dddd 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/GeographicRegion.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
     /**
    @@ -91,7 +90,7 @@ public static GeographicRegion getInstance(Object o)
             }
             if (o != null)
             {
    -            return new GeographicRegion(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new GeographicRegion(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java
    index 9ebfd332ae..7bdf5f7ef3 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/IdentifiedRegion.java
    @@ -5,10 +5,8 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
    -
     /**
      * IdentifiedRegion ::= CHOICE {
      * countryOnly           CountryOnly,
    @@ -79,7 +77,7 @@ public static IdentifiedRegion getInstance(Object o)
             }
             if (o != null)
             {
    -            return new IdentifiedRegion(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new IdentifiedRegion(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java
    index f5a733b8c9..a6da63d689 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/PublicVerificationKey.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DEROctetString;
     import org.bouncycastle.asn1.DERTaggedObject;
     
    @@ -79,7 +78,7 @@ public static PublicVerificationKey getInstance(Object object)
     
             if (object != null)
             {
    -            return new PublicVerificationKey(ASN1TaggedObject.getInstance(object, BERTags.CONTEXT_SPECIFIC));
    +            return new PublicVerificationKey(ASN1TaggedObject.getContextInstance(object));
             }
             return null;
         }
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/RectangularRegion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/RectangularRegion.java
    index 65647ae7cb..a3893d2824 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/RectangularRegion.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/RectangularRegion.java
    @@ -99,4 +99,4 @@ public RectangularRegion createRectangularRegion()
             }
         }
     
    -}
    \ No newline at end of file
    +}
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java
    index e49fdb26db..8d9b7f99e2 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/ServiceSpecificPermissions.java
    @@ -6,7 +6,6 @@
     import org.bouncycastle.asn1.ASN1OctetString;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DEROctetString;
     import org.bouncycastle.asn1.DERTaggedObject;
     import org.bouncycastle.oer.its.ieee1609dot2.Opaque;
    @@ -61,7 +60,7 @@ public static ServiceSpecificPermissions getInstance(Object o)
     
             if (o != null)
             {
    -            return new ServiceSpecificPermissions(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new ServiceSpecificPermissions(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java
    index cdd54e9d1d..2d3f103fb6 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/Signature.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     
     /**
    @@ -79,7 +78,7 @@ public static Signature getInstance(Object objectAt)
     
             if (objectAt != null)
             {
    -            return new Signature(ASN1TaggedObject.getInstance(objectAt, BERTags.CONTEXT_SPECIFIC));
    +            return new Signature(ASN1TaggedObject.getContextInstance(objectAt));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java
    index 65c31cdb53..9dd4593b62 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SspRange.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERNull;
     import org.bouncycastle.asn1.DERTaggedObject;
     
    @@ -82,7 +81,7 @@ public static SspRange getInstance(Object src)
     
             if (src != null)
             {
    -            return new SspRange(ASN1TaggedObject.getInstance(src, BERTags.CONTEXT_SPECIFIC));
    +            return new SspRange(ASN1TaggedObject.getContextInstance(src));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java
    index c573c01488..be7d0c8761 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2/basetypes/SymmetricEncryptionKey.java
    @@ -6,7 +6,6 @@
     import org.bouncycastle.asn1.ASN1OctetString;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DEROctetString;
     import org.bouncycastle.asn1.DERTaggedObject;
     
    @@ -59,7 +58,7 @@ public static SymmetricEncryptionKey getInstance(Object o)
             }
             if (o != null)
             {
    -            return new SymmetricEncryptionKey(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new SymmetricEncryptionKey(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java
    index 79eb52733e..2bab58de0d 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/AdditionalParams.java
    @@ -5,7 +5,6 @@
     import org.bouncycastle.asn1.ASN1Object;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DERTaggedObject;
     import org.bouncycastle.oer.its.ieee1609dot2.basetypes.PublicEncryptionKey;
     
    @@ -68,7 +67,7 @@ public static AdditionalParams getInstance(Object o)
     
             if (o != null)
             {
    -            return new AdditionalParams(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new AdditionalParams(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java
    index 45e614c0cc..db45276208 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/ieee1609dot2dot1/ButterflyExpansion.java
    @@ -6,11 +6,9 @@
     import org.bouncycastle.asn1.ASN1OctetString;
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.DEROctetString;
     import org.bouncycastle.asn1.DERTaggedObject;
     
    -
     /**
      * ButterflyExpansion ::= CHOICE {
      * aes128      OCTET STRING (SIZE(16)),
    @@ -55,7 +53,7 @@ public static ButterflyExpansion getInstance(Object o)
     
             if (o != null)
             {
    -            return new ButterflyExpansion(ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC));
    +            return new ButterflyExpansion(ASN1TaggedObject.getContextInstance(o));
             }
     
             return null;
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java b/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java
    index 333008cbe4..bbd32ff273 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/template/etsi103097/extension/EtsiTs103097ExtensionModule.java
    @@ -17,8 +17,8 @@
     public class EtsiTs103097ExtensionModule
     {
     
    -    public static final ASN1Integer etsiTs102941CrlRequestId = new ASN1Integer(1);
    -    public static final ASN1Integer etsiTs102941DeltaCtlRequestId = new ASN1Integer(2);
    +    public static final ASN1Integer etsiTs102941CrlRequestId = ASN1Integer.ONE;
    +    public static final ASN1Integer etsiTs102941DeltaCtlRequestId = ASN1Integer.TWO;
         private static final ASN1Encodable[] extensionKeys = new ASN1Encodable[]{etsiTs102941CrlRequestId, etsiTs102941DeltaCtlRequestId};
     
         /**
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/IEEE1609dot2.java b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/IEEE1609dot2.java
    index 37bf6add62..3e3987add3 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/IEEE1609dot2.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/IEEE1609dot2.java
    @@ -624,7 +624,7 @@ public Element build()
          * }
          */
         public static final OERDefinition.Builder Ieee1609Dot2Data = OERDefinition.seq(
    -        Ieee1609Dot2BaseTypes.UINT8.validSwitchValue(new ASN1Integer(3)).label("protocolVersion"),
    +        Ieee1609Dot2BaseTypes.UINT8.validSwitchValue(ASN1Integer.THREE).label("protocolVersion"),
             Ieee1609Dot2Content.label("content")).typeName("Ieee1609Dot2Data");
         /**
          * SignedDataPayload ::= SEQUENCE {
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/basetypes/Ieee1609Dot2BaseTypes.java b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/basetypes/Ieee1609Dot2BaseTypes.java
    index 7b87b10605..e7ad1f3bce 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/basetypes/Ieee1609Dot2BaseTypes.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2/basetypes/Ieee1609Dot2BaseTypes.java
    @@ -497,7 +497,7 @@ public class Ieee1609Dot2BaseTypes
          */
         public static final OERDefinition.Builder OneEightyDegreeInt = OERDefinition.integer(-1799999999, 1800000001).typeName("OneEightyDegreeInt");
         public static final OERDefinition.Builder KnownLongitude = OneEightyDegreeInt.copy().typeName("KnownLongitude");
    -    public static final OERDefinition.Builder UnknownLongitude = OERDefinition.integer().validSwitchValue(new ASN1Integer(1800000001)).typeName("UnknownLongitude");
    +    public static final OERDefinition.Builder UnknownLongitude = OERDefinition.integer().validSwitchValue(ASN1Integer.valueOf(1800000001)).typeName("UnknownLongitude");
         /**
          * NinetyDegreeInt ::= INTEGER {
          * min         (-900000000),
    @@ -510,7 +510,7 @@ public class Ieee1609Dot2BaseTypes
         //
         // PSID / ITS-AID
         //
    -    public static final OERDefinition.Builder UnknownLatitude = OERDefinition.integer().validSwitchValue(new ASN1Integer(900000001)).typeName("UnknownLatitude");
    +    public static final OERDefinition.Builder UnknownLatitude = OERDefinition.integer().validSwitchValue(ASN1Integer.valueOf(900000001)).typeName("UnknownLatitude");
         public static final OERDefinition.Builder Elevation = UINT16.typeName("Elevation");
         public static final OERDefinition.Builder Longitude = OneEightyDegreeInt.copy().typeName("Longitude");
         public static final OERDefinition.Builder Latitude = NinetyDegreeInt.copy().typeName("Latitude");
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EcaEeInterface.java b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EcaEeInterface.java
    index e47d6ed305..716857f271 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EcaEeInterface.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EcaEeInterface.java
    @@ -33,7 +33,7 @@ public class Ieee1609Dot2Dot1EcaEeInterface
          * }
          */
         public static final OERDefinition.Builder EeEcaCertRequest = OERDefinition.seq(
    -        Ieee1609Dot2BaseTypes.UINT8.label("version").validSwitchValue(new ASN1Integer(2)),
    +        Ieee1609Dot2BaseTypes.UINT8.label("version").validSwitchValue(ASN1Integer.TWO),
             Ieee1609Dot2BaseTypes.Time32.label("generationTime"),
             IEEE1609dot2.CertificateType.label("type"),
             IEEE1609dot2.ToBeSignedCertificate.label("tbsCert"),
    diff --git a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EeRaInterface.java b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EeRaInterface.java
    index 4f757019cf..60344867d8 100644
    --- a/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EeRaInterface.java
    +++ b/util/src/main/java/org/bouncycastle/oer/its/template/ieee1609dot2dot1/Ieee1609Dot2Dot1EeRaInterface.java
    @@ -72,7 +72,7 @@ public class Ieee1609Dot2Dot1EeRaInterface
          * }
          */
         public static final OERDefinition.Builder EeRaCertRequest = OERDefinition.seq(
    -        Ieee1609Dot2BaseTypes.UINT8.label("version").validSwitchValue(new ASN1Integer(2)),
    +        Ieee1609Dot2BaseTypes.UINT8.label("version").validSwitchValue(ASN1Integer.TWO),
             Ieee1609Dot2BaseTypes.Time32.label("generationTime"),
             IEEE1609dot2.CertificateType.label("type"),
             IEEE1609dot2.ToBeSignedCertificate.label("tbsCert"),
    diff --git a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java
    index 24cfcc801c..a73f84fa7d 100644
    --- a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java
    +++ b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/CertAnnContent.java
    @@ -6,7 +6,6 @@
     import org.bouncycastle.asn1.ASN1Primitive;
     import org.bouncycastle.asn1.ASN1Sequence;
     import org.bouncycastle.asn1.ASN1TaggedObject;
    -import org.bouncycastle.asn1.BERTags;
     import org.bouncycastle.asn1.x509.AttributeCertificate;
     import org.bouncycastle.asn1.x509.Certificate;
     
    @@ -92,7 +91,7 @@ public static CMPCertificate getInstance(Object o)
     
             if (o instanceof ASN1TaggedObject)
             {
    -            ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC);
    +            ASN1TaggedObject taggedObject = ASN1TaggedObject.getContextInstance(o);
     
                 return new CertAnnContent(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject());
             }
    diff --git a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java
    index 30f0f7641a..4324d935bd 100644
    --- a/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java
    +++ b/util/src/main/jdk1.4/org/bouncycastle/asn1/cmp/OOBCert.java
    @@ -87,7 +87,7 @@ public static CMPCertificate getInstance(Object o)
     
             if (o instanceof ASN1TaggedObject)
             {
    -            ASN1TaggedObject taggedObject = ASN1TaggedObject.getInstance(o, BERTags.CONTEXT_SPECIFIC);
    +            ASN1TaggedObject taggedObject = ASN1TaggedObject.getContextInstance(o);
     
                 return new OOBCert(taggedObject.getTagNo(), taggedObject.getExplicitBaseObject());
             }
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java
    index 774a4e2b2b..206aefd80b 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCFailInfoTest.java
    @@ -73,7 +73,7 @@ public void performTest()
             for (Iterator typeKeys = typesMap.keySet().iterator(); typeKeys.hasNext(); )
             {
                 Object j = typeKeys.next();
    -            if (!range.containsKey(new ASN1Integer(((Long)j).longValue())))
    +            if (!range.containsKey(ASN1Integer.valueOf(((Long)j).longValue())))
                 {
                     fail("The 'typesMap' map in CMCFailInfoTest contains a value not in the CMCFailInfo ('range') map, value was: " + j.toString());
                 }
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java
    index 683a4db298..9f8aa78308 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCStatusTest.java
    @@ -77,7 +77,7 @@ public void performTest()
             for (Iterator typeKeys = typesMap.keySet().iterator(); typeKeys.hasNext(); )
             {
                 Object j = typeKeys.next();
    -            if (!range.containsKey(new ASN1Integer(((Long)j).longValue())))
    +            if (!range.containsKey(ASN1Integer.valueOf(((Long)j).longValue())))
                 {
                     fail("The 'typesMap' map in CMCStatusTest contains a value not in the CMCStatus ('range') map, value was: " + j.toString());
                 }
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCUnsignedDataTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCUnsignedDataTest.java
    index b9548afd76..64cb5f1b3e 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCUnsignedDataTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/CMCUnsignedDataTest.java
    @@ -41,7 +41,7 @@ public void performTest()
     
             try
             {
    -            CMCUnsignedData.getInstance(new DERSequence(new ASN1Integer(10)));
    +            CMCUnsignedData.getInstance(new DERSequence(ASN1Integer.valueOf(10)));
                 fail("Must fail, sequence must be 3");
             }
             catch (Exception ex)
    @@ -51,7 +51,7 @@ public void performTest()
     
             try
             {
    -            CMCUnsignedData.getInstance(new DERSequence(new ASN1Encodable[]{new ASN1Integer(10), new ASN1Integer(10), new ASN1Integer(10), new ASN1Integer(10)}));
    +            CMCUnsignedData.getInstance(new DERSequence(new ASN1Encodable[]{ASN1Integer.valueOf(10), ASN1Integer.valueOf(10), ASN1Integer.valueOf(10), ASN1Integer.valueOf(10)}));
                 fail("Must fail, sequence must be 3");
             }
             catch (Exception ex)
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/ControlsProcessedTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/ControlsProcessedTest.java
    index 413144447d..60ac9427ac 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/ControlsProcessedTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/ControlsProcessedTest.java
    @@ -1,6 +1,5 @@
     package org.bouncycastle.asn1.cmc.test;
     
    -import org.bouncycastle.asn1.ASN1Encodable;
     import org.bouncycastle.asn1.ASN1Integer;
     import org.bouncycastle.asn1.DERSequence;
     import org.bouncycastle.asn1.DERUTF8String;
    @@ -38,9 +37,7 @@ public void performTest()
     
             try
             {
    -            ControlsProcessed.getInstance(new DERSequence(
    -                new ASN1Encodable[]{new ASN1Integer(12L), new DERUTF8String("Monkeys")
    -                }));
    +            ControlsProcessed.getInstance(new DERSequence(ASN1Integer.valueOf(12), new DERUTF8String("Monkeys")));
                 fail("Must accept only sequence length of 1");
             }
             catch (Throwable t)
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/EncryptedPOPTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/EncryptedPOPTest.java
    index 074c1ad699..8597763135 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/EncryptedPOPTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/EncryptedPOPTest.java
    @@ -34,7 +34,7 @@ public void performTest()
         {
             // All Object Identifiers are not real!
             TaggedRequest taggedRequest = new TaggedRequest(new TaggedCertificationRequest(new BodyPartID(10L), CertificationRequest.getInstance(req1)));
    -        ContentInfo cms = new ContentInfo(new ASN1ObjectIdentifier("1.2.3"), new ASN1Integer(12L));
    +        ContentInfo cms = new ContentInfo(new ASN1ObjectIdentifier("1.2.3"), ASN1Integer.valueOf(12));
             AlgorithmIdentifier thePopID = new AlgorithmIdentifier(new ASN1ObjectIdentifier("2.2.5.2"));
             AlgorithmIdentifier whitenessID = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.5.2.5"));
             byte[] whiteness = "Fish and Chips".getBytes();
    @@ -53,7 +53,7 @@ public void performTest()
     
             try
             {
    -            EncryptedPOP.getInstance(new DERSequence(new ASN1Integer(1L)));
    +            EncryptedPOP.getInstance(new DERSequence(ASN1Integer.ONE));
                 fail("Sequence must be 5 items long.");
             }
             catch (Throwable t)
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/ExtendedFailInfoTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/ExtendedFailInfoTest.java
    index bd947fc411..762388b13d 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/ExtendedFailInfoTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/ExtendedFailInfoTest.java
    @@ -27,7 +27,7 @@ public void performTest()
             // OID not real
             ExtendedFailInfo extendedFailInfo = new ExtendedFailInfo(
                 new ASN1ObjectIdentifier("1.2.3.2"),
    -            new ASN1Integer(10L));
    +            ASN1Integer.valueOf(10));
             byte[] b = extendedFailInfo.getEncoded();
             ExtendedFailInfo extendedFailInfoResult = ExtendedFailInfo.getInstance(b);
     
    @@ -36,7 +36,7 @@ public void performTest()
     
             try
             {
    -            ExtendedFailInfo.getInstance(new DERSequence(new ASN1Integer(10L)));
    +            ExtendedFailInfo.getInstance(new DERSequence(ASN1Integer.valueOf(10)));
                 fail("Sequence must be 2 elements.");
             }
             catch (Throwable t)
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCRLTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCRLTest.java
    index 68eed5ae78..ba8fa51a33 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCRLTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCRLTest.java
    @@ -64,8 +64,8 @@ public void performTest()
     
                 try
                 {
    -                GetCRL.getInstance(new DERSequence(new ASN1Encodable[]
    -                    { new ASN1Integer(1), new ASN1Integer(2), new ASN1Integer(3), new ASN1Integer(4), new ASN1Integer(5)}));
    +                GetCRL.getInstance(new DERSequence(new ASN1Encodable[]{
    +                    ASN1Integer.ONE, ASN1Integer.TWO, ASN1Integer.THREE, ASN1Integer.FOUR, ASN1Integer.FIVE}));
                     fail("Must not accept sequence larger than 5");
                 }
                 catch (Throwable t)
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCertTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCertTest.java
    index 0a03e6da0b..e0a41f94de 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCertTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/GetCertTest.java
    @@ -34,7 +34,7 @@ public void performTest()
     
             try
             {
    -            GetCert.getInstance(new DERSequence(new ASN1Integer(1L)));
    +            GetCert.getInstance(new DERSequence(ASN1Integer.ONE));
                 fail("Sequence must be length of 2");
             }
             catch (Throwable t)
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/IdentityProofV2Test.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/IdentityProofV2Test.java
    index 83d161f14d..96b3a952b7 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/IdentityProofV2Test.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/IdentityProofV2Test.java
    @@ -26,8 +26,8 @@ public void performTest()
             throws Exception
         {
             IdentityProofV2 proofV2 = new IdentityProofV2(
    -            new AlgorithmIdentifier(PKCSObjectIdentifiers.encryptionAlgorithm, new ASN1Integer(10L)),
    -            new AlgorithmIdentifier(PKCSObjectIdentifiers.bagtypes, new ASN1Integer(10L)),
    +            new AlgorithmIdentifier(PKCSObjectIdentifiers.encryptionAlgorithm, ASN1Integer.valueOf(10)),
    +            new AlgorithmIdentifier(PKCSObjectIdentifiers.bagtypes, ASN1Integer.valueOf(10)),
                 "Cats".getBytes()
             );
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/LraPopWitnessTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/LraPopWitnessTest.java
    index b0c881618c..9674dc18b1 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/LraPopWitnessTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/LraPopWitnessTest.java
    @@ -25,7 +25,7 @@ public String getName()
         public void performTest()
             throws Exception
         {
    -        LraPopWitness popWitness = new LraPopWitness(new BodyPartID(10L), new DERSequence(new ASN1Integer(20L)));
    +        LraPopWitness popWitness = new LraPopWitness(new BodyPartID(10L), new DERSequence(ASN1Integer.valueOf(20)));
             byte[] b = popWitness.getEncoded();
             LraPopWitness popWitnessResult = LraPopWitness.getInstance(b);
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/ModCertTemplateTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/ModCertTemplateTest.java
    index 3706368562..4bd5017748 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/ModCertTemplateTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/ModCertTemplateTest.java
    @@ -33,7 +33,7 @@ public void performTest()
             BodyPartPath pkiDataReference = new BodyPartPath(new BodyPartID(10L));
             BodyPartList certReferences = new BodyPartList(new BodyPartID(12L));
             boolean replace = false;
    -        CertTemplate certTemplate = CertTemplate.getInstance(new DLSequence(new DERTaggedObject(false, 1, new ASN1Integer(34L))));
    +        CertTemplate certTemplate = CertTemplate.getInstance(new DLSequence(new DERTaggedObject(false, 1, ASN1Integer.valueOf(34))));
             {
                 ModCertTemplate modCertTemplate = new ModCertTemplate(
                     pkiDataReference,
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/OtherStatusInfoTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/OtherStatusInfoTest.java
    index 3e4640413b..1a8bbc3108 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/OtherStatusInfoTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/OtherStatusInfoTest.java
    @@ -54,7 +54,7 @@ public void performTest()
     
             {
                 OtherStatusInfo ose = OtherStatusInfo.getInstance(
    -                new ExtendedFailInfo(PKCSObjectIdentifiers.canNotDecryptAny, new ASN1Integer(10L)));
    +                new ExtendedFailInfo(PKCSObjectIdentifiers.canNotDecryptAny, ASN1Integer.valueOf(10)));
                 byte[] b = ose.getEncoded();
                 OtherStatusInfo oseResult = OtherStatusInfo.getInstance(b);
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIDataTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIDataTest.java
    index f987a0eae0..f16135f3df 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIDataTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIDataTest.java
    @@ -46,8 +46,8 @@ public void performTest()
             PKIData pkiData = new PKIData(
                 new TaggedAttribute[]{new TaggedAttribute(new BodyPartID(10L), PKCSObjectIdentifiers.id_aa, new DERSet())},
                 new TaggedRequest[]{new TaggedRequest(new TaggedCertificationRequest(new BodyPartID(10L), CertificationRequest.getInstance(req1)))},
    -            new TaggedContentInfo[]{new TaggedContentInfo(new BodyPartID(10L), new ContentInfo(PKCSObjectIdentifiers.id_aa_ets_commitmentType, new ASN1Integer(10L)))},
    -            new OtherMsg[]{new OtherMsg(new BodyPartID(10L), PKCSObjectIdentifiers.pkcs_9, new ASN1Integer(10L))});
    +            new TaggedContentInfo[]{new TaggedContentInfo(new BodyPartID(10L), new ContentInfo(PKCSObjectIdentifiers.id_aa_ets_commitmentType, ASN1Integer.valueOf(10)))},
    +            new OtherMsg[]{new OtherMsg(new BodyPartID(10L), PKCSObjectIdentifiers.pkcs_9, ASN1Integer.valueOf(10))});
     
     
             byte[] b = pkiData.getEncoded();
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIResponseTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIResponseTest.java
    index 17d3064a28..58f1b15a72 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIResponseTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PKIResponseTest.java
    @@ -33,7 +33,7 @@ public void performTest()
         {
             PKIResponse pkiResponse = PKIResponse.getInstance(new DERSequence(new ASN1Encodable[]{
                 new DERSequence(new TaggedAttribute(new BodyPartID(10L), PKCSObjectIdentifiers.bagtypes, new DERSet())),
    -            new DERSequence(new TaggedContentInfo(new BodyPartID(12L), new ContentInfo(PKCSObjectIdentifiers.id_aa, new ASN1Integer(10L)))),
    +            new DERSequence(new TaggedContentInfo(new BodyPartID(12L), new ContentInfo(PKCSObjectIdentifiers.id_aa, ASN1Integer.valueOf(10)))),
                 new DERSequence(new OtherMsg(new BodyPartID(12), PKCSObjectIdentifiers.id_aa_msgSigDigest, new DERUTF8String("foo")))
             }));
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PopLinkWitnessV2Test.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PopLinkWitnessV2Test.java
    index aaa16765d6..e136d7fbc9 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PopLinkWitnessV2Test.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PopLinkWitnessV2Test.java
    @@ -26,8 +26,8 @@ public void performTest()
         {
             // Object identifiers real but not correct in this context.
             PopLinkWitnessV2 popLinkWitnessV2 = new PopLinkWitnessV2(
    -            new AlgorithmIdentifier(PKCSObjectIdentifiers.bagtypes, new ASN1Integer(10L)),
    -            new AlgorithmIdentifier(PKCSObjectIdentifiers.crlTypes, new ASN1Integer(12L)),
    +            new AlgorithmIdentifier(PKCSObjectIdentifiers.bagtypes, ASN1Integer.valueOf(10)),
    +            new AlgorithmIdentifier(PKCSObjectIdentifiers.crlTypes, ASN1Integer.valueOf(12)),
                 "cats".getBytes()
             );
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PublishTrustAnchorsTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PublishTrustAnchorsTest.java
    index 0f7fe4557e..fad4ee9b05 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/PublishTrustAnchorsTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/PublishTrustAnchorsTest.java
    @@ -27,8 +27,9 @@ public void performTest()
             throws Exception
         {
             PublishTrustAnchors publishTrustAnchors = new PublishTrustAnchors(
    -            new BigInteger("10"), new AlgorithmIdentifier(PKCSObjectIdentifiers.crlTypes,
    -            new ASN1Integer(5L)), new byte[][]{"cats".getBytes()});
    +            BigInteger.valueOf(10),
    +            new AlgorithmIdentifier(PKCSObjectIdentifiers.crlTypes, ASN1Integer.FIVE),
    +            new byte[][]{"cats".getBytes()});
     
             byte[] b = publishTrustAnchors.getEncoded();
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/RevokeRequestTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/RevokeRequestTest.java
    index 3d4baefa57..bf5596a308 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/RevokeRequestTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/RevokeRequestTest.java
    @@ -63,7 +63,7 @@ public void performTest()
     
                 RevokeRequest rr = new RevokeRequest(
                     name,
    -                new ASN1Integer(12L),
    +                ASN1Integer.valueOf(12),
                     CRLReason.getInstance(new ASN1Enumerated(CRLReason.certificateHold)),
                     invalidityDate,
                     passphrase,
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedAttributeTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedAttributeTest.java
    index f400bd4da6..edb02fef8e 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedAttributeTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedAttributeTest.java
    @@ -48,7 +48,7 @@ public void performTest()
             //
             try
             {
    -            ASN1Sequence seq = new DERSequence(new ASN1Encodable[] { new BodyPartID(10) });
    +            ASN1Sequence seq = new DERSequence(new BodyPartID(10));
     
                 TaggedAttribute.getInstance(seq);
                 fail("no exception");
    @@ -63,7 +63,8 @@ public void performTest()
             //
             try
             {
    -            ASN1Sequence seq = new DERSequence(new ASN1Encodable[] { ta.getBodyPartID(), ta.getAttrType(), ta.getAttrValues(), new ASN1Integer(0)});
    +            ASN1Sequence seq = new DERSequence(new ASN1Encodable[]{
    +                ta.getBodyPartID(), ta.getAttrType(), ta.getAttrValues(), ASN1Integer.ZERO });
     
                 TaggedAttribute.getInstance(seq);
                 fail("no exception");
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedRequestTest.java b/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedRequestTest.java
    index e98113c724..7ea48482cf 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedRequestTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cmc/test/TaggedRequestTest.java
    @@ -67,12 +67,11 @@ public void performTest()
     
                 POPOSigningKeyInput pski = new POPOSigningKeyInput(
                     new GeneralName(GeneralName.rfc822Name, "fish"),
    -                new SubjectPublicKeyInfo(new AlgorithmIdentifier(
    -                    PKCSObjectIdentifiers.certBag,
    -                    new ASN1Integer(5L)), new ASN1Integer(4L)
    -                ));
    +                new SubjectPublicKeyInfo(
    +                    new AlgorithmIdentifier(PKCSObjectIdentifiers.certBag, ASN1Integer.FIVE),
    +                    ASN1Integer.FOUR));
     
    -            AlgorithmIdentifier aid = new AlgorithmIdentifier(PKCSObjectIdentifiers.crlTypes, new ASN1Integer(1L));
    +            AlgorithmIdentifier aid = new AlgorithmIdentifier(PKCSObjectIdentifiers.crlTypes, ASN1Integer.ONE);
                 DERBitString dbi = new DERBitString(2);
     
                 POPOSigningKey popoSigningKey = new POPOSigningKey(pski, aid, dbi);
    @@ -80,12 +79,11 @@ public void performTest()
     
                 TaggedRequest tr = new TaggedRequest(
                     new CertReqMsg(new CertRequest(
    -                    new ASN1Integer(1L),
    -                    CertTemplate.getInstance(new DERSequence(new DERTaggedObject(false, 0, new ASN1Integer(3L)))),
    -                    new Controls(new AttributeTypeAndValue(PKCSObjectIdentifiers.pkcs_9,new ASN1Integer(3)))),
    +                    ASN1Integer.ONE,
    +                    CertTemplate.getInstance(new DERSequence(new DERTaggedObject(false, 0, ASN1Integer.THREE))),
    +                    new Controls(new AttributeTypeAndValue(PKCSObjectIdentifiers.pkcs_9, ASN1Integer.THREE))),
                         proofOfPossession,
    -                    new AttributeTypeAndValue[0])
    -            );
    +                    new AttributeTypeAndValue[0]));
                 byte[] b = tr.getEncoded();
                 TaggedRequest trResult = TaggedRequest.getInstance(b);
                 isEquals("Tag", tr.getTagNo(), trResult.getTagNo());
    @@ -95,11 +93,8 @@ public void performTest()
     
     
             { // ORM
    -            TaggedRequest tr = TaggedRequest.getInstance( new DERTaggedObject(false, TaggedRequest.ORM, new DERSequence(new ASN1Encodable[]{
    -                new BodyPartID(1L),
    -                PKCSObjectIdentifiers.data,
    -                new DERSet(new ASN1Encodable[]{new ASN1Integer(5L)})
    -            })));
    +            TaggedRequest tr = TaggedRequest.getInstance(new DERTaggedObject(false, TaggedRequest.ORM,
    +                new DERSequence(new ASN1Encodable[]{new BodyPartID(1L), PKCSObjectIdentifiers.data, new DERSet(ASN1Integer.FIVE)})));
                 byte[] b = tr.getEncoded();
                 TaggedRequest trResult = TaggedRequest.getInstance(b);
                 isEquals("Tag", tr.getTagNo(), trResult.getTagNo());
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cms/test/KEMRecipientInfoTest.java b/util/src/test/java/org/bouncycastle/asn1/cms/test/KEMRecipientInfoTest.java
    index acb796978b..ab8feb2359 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cms/test/KEMRecipientInfoTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cms/test/KEMRecipientInfoTest.java
    @@ -28,7 +28,7 @@ public void testOutOfRange()
                     new AlgorithmIdentifier(NISTObjectIdentifiers.id_alg_ml_kem_512),
                     new DEROctetString(new byte[0]),
                     new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3),
    -                new ASN1Integer(700000), new DEROctetString(new byte[0]),
    +                ASN1Integer.valueOf(700000), new DEROctetString(new byte[0]),
                     new AlgorithmIdentifier(NISTObjectIdentifiers.id_aes256_wrap_pad),
                     new DEROctetString(new byte[0]));
                 fail("no exception");
    @@ -59,7 +59,7 @@ public void testNullWrap()
                     new AlgorithmIdentifier(NISTObjectIdentifiers.id_alg_ml_kem_512),
                     new DEROctetString(new byte[0]),
                     new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3),
    -                new ASN1Integer(7000), new DEROctetString(new byte[0]),
    +                ASN1Integer.valueOf(7000), new DEROctetString(new byte[0]),
                     null,
                     new DEROctetString(new byte[0]));
                 fail("no exception");
    @@ -80,7 +80,7 @@ public void testNullKem()
                     null,
                     new DEROctetString(new byte[0]),
                     new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3),
    -                new ASN1Integer(7000), new DEROctetString(new byte[0]),
    +                ASN1Integer.valueOf(7000), new DEROctetString(new byte[0]),
                     new AlgorithmIdentifier(NISTObjectIdentifiers.id_aes256_wrap_pad),
                     new DEROctetString(new byte[0]));
                 fail("no exception");
    @@ -109,7 +109,7 @@ public void testSequenceSize()
                 ASN1Encodable[] elements = new ASN1Encodable[10];
                 for (int i = 0; i != elements.length; i++)
                 {
    -                elements[i] = new ASN1Integer(1);
    +                elements[i] = ASN1Integer.ONE;
                 }
                 KEMRecipientInfo.getInstance(new DERSequence(elements));
                 fail("no exception");
    diff --git a/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java b/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java
    index 4f7ac2e7ad..3fd472d265 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/cms/test/OctetStringTest.java
    @@ -161,7 +161,7 @@ public void testNestedStructure()
     
             BERSequenceGenerator cGen = new BERSequenceGenerator(sGen.getRawOutputStream(), 0, true);
             
    -        cGen.addObject(new ASN1Integer(0));
    +        cGen.addObject(ASN1Integer.ZERO);
             
             //
             // AlgorithmIdentifier
    diff --git a/util/src/test/java/org/bouncycastle/asn1/ess/test/OtherCertIDUnitTest.java b/util/src/test/java/org/bouncycastle/asn1/ess/test/OtherCertIDUnitTest.java
    index 467bfac382..450d6ab8cb 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/ess/test/OtherCertIDUnitTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/ess/test/OtherCertIDUnitTest.java
    @@ -27,7 +27,7 @@ public void performTest()
         {
             AlgorithmIdentifier algId = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.2.3"));
             byte[]              digest = new byte[20];
    -        IssuerSerial        issuerSerial = new IssuerSerial(new GeneralNames(new GeneralName(new X500Name("CN=test"))), new ASN1Integer(1));
    +        IssuerSerial        issuerSerial = new IssuerSerial(new GeneralNames(new GeneralName(new X500Name("CN=test"))), ASN1Integer.ONE);
     
             OtherCertID certID = new OtherCertID(algId, digest);
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/isismtt/test/ProcurationSyntaxUnitTest.java b/util/src/test/java/org/bouncycastle/asn1/isismtt/test/ProcurationSyntaxUnitTest.java
    index e3eeddceb7..bd57b2c116 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/isismtt/test/ProcurationSyntaxUnitTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/isismtt/test/ProcurationSyntaxUnitTest.java
    @@ -27,7 +27,7 @@ public void performTest()
             String country = "AU";
             DirectoryString  typeOfSubstitution = new DirectoryString("substitution");
             GeneralName thirdPerson = new GeneralName(new X500Name("CN=thirdPerson"));
    -        IssuerSerial certRef = new IssuerSerial(new GeneralNames(new GeneralName(new X500Name("CN=test"))), new ASN1Integer(1));
    +        IssuerSerial certRef = new IssuerSerial(new GeneralNames(new GeneralName(new X500Name("CN=test"))), ASN1Integer.ONE);
     
             ProcurationSyntax procuration = new ProcurationSyntax(country, typeOfSubstitution, thirdPerson);
     
    diff --git a/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java b/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java
    index d13cc6cd4f..e14e670752 100644
    --- a/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java
    +++ b/util/src/test/java/org/bouncycastle/asn1/misc/test/GetInstanceTest.java
    @@ -492,7 +492,7 @@ public void testGetInstance()
             doFullGetInstanceTest(DERT61String.class, new DERT61String("hello world"));
             doFullGetInstanceTest(DERVisibleString.class, new DERVisibleString("hello world"));
     
    -        doFullGetInstanceTest(ASN1Integer.class, new ASN1Integer(1));
    +        doFullGetInstanceTest(ASN1Integer.class, ASN1Integer.ONE);
             doFullGetInstanceTest(ASN1GeneralizedTime.class, new ASN1GeneralizedTime(new Date()));
             doFullGetInstanceTest(ASN1UTCTime.class, new ASN1UTCTime(new Date()));
             doFullGetInstanceTest(ASN1Enumerated.class, new ASN1Enumerated(1));
    @@ -507,13 +507,13 @@ public void testGetInstance()
             CertifiedKeyPair.getInstance(null);
             CertOrEncCert.getInstance(null);
             CertRepMessage.getInstance(null);
    -        doFullGetInstanceTest(CertResponse.class, new CertResponse(new ASN1Integer(1), new PKIStatusInfo(PKIStatus.granted)));
    +        doFullGetInstanceTest(CertResponse.class, new CertResponse(ASN1Integer.ONE, new PKIStatusInfo(PKIStatus.granted)));
             doFullGetInstanceTest(org.bouncycastle.asn1.cmp.CertStatus.class, new org.bouncycastle.asn1.cmp.CertStatus(new byte[10], BigInteger.valueOf(1), new PKIStatusInfo(PKIStatus.granted), new AlgorithmIdentifier(new ASN1ObjectIdentifier("0.0"))));
             doFullGetInstanceTest(Challenge.class, new Challenge(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new byte[10], new byte[10]));
     
             doFullGetInstanceTest(CMPCertificate.class, cmpCert);
             doFullGetInstanceTest(CRLAnnContent.class, new CRLAnnContent(crl));
    -        doFullGetInstanceTest(ErrorMsgContent.class, new ErrorMsgContent(new PKIStatusInfo(PKIStatus.granted), new ASN1Integer(1), new PKIFreeText("fred")));
    +        doFullGetInstanceTest(ErrorMsgContent.class, new ErrorMsgContent(new PKIStatusInfo(PKIStatus.granted), ASN1Integer.ONE, new PKIFreeText("fred")));
             GenMsgContent.getInstance(null);
             GenRepContent.getInstance(null);
             InfoTypeAndValue.getInstance(null);
    @@ -695,7 +695,7 @@ public void testGetInstance()
             BasicOCSPResponse.getInstance(null);
             BasicOCSPResponse.getInstance(null);
     
    -        doFullGetInstanceTest(CertID.class, new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new DEROctetString(new byte[1]), new DEROctetString(new byte[1]), new ASN1Integer(1)));
    +        doFullGetInstanceTest(CertID.class, new CertID(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new DEROctetString(new byte[1]), new DEROctetString(new byte[1]), ASN1Integer.ONE));
     
             CertStatus.getInstance(null);
             CertStatus.getInstance(null);
    @@ -895,14 +895,11 @@ public void testGetInstance()
             PersonalData.getInstance(null);
     
             doFullGetInstanceTest(CertReqTemplateContent.class, new DERSequence(
    -            new ASN1Encodable[]{
    -                CertTemplate.getInstance(new DLSequence(new DERTaggedObject(false, 1, new ASN1Integer(34L)))),
    -                new DERSequence(new ASN1Encodable[]{new AttributeTypeAndValue(CMPObjectIdentifiers.id_regCtrl_algId, new DERUTF8String("test"))})
    -            }));
    +            CertTemplate.getInstance(new DLSequence(new DERTaggedObject(false, 1, ASN1Integer.valueOf(34)))),
    +            new DERSequence(new AttributeTypeAndValue(CMPObjectIdentifiers.id_regCtrl_algId, new DERUTF8String("test")))));
     
             doFullGetInstanceTest(CertReqTemplateContent.class, new DERSequence(
    -            new ASN1Encodable[]{
    -                CertTemplate.getInstance(new DLSequence(new DERTaggedObject(false, 1, new ASN1Integer(34L))))}));
    +            CertTemplate.getInstance(new DLSequence(new DERTaggedObject(false, 1, ASN1Integer.valueOf(34))))));
     
             doFullGetInstanceTest(CRLSource.class,
                 new DERTaggedObject(true, 0, new DistributionPointName(new GeneralNames(new GeneralName(GeneralName.dNSName, new DERIA5String("cats"))))));
    diff --git a/util/src/test/java/org/bouncycastle/oer/test/ExtensionTest.java b/util/src/test/java/org/bouncycastle/oer/test/ExtensionTest.java
    index 319e9c06ca..0ca3c9f62a 100644
    --- a/util/src/test/java/org/bouncycastle/oer/test/ExtensionTest.java
    +++ b/util/src/test/java/org/bouncycastle/oer/test/ExtensionTest.java
    @@ -39,7 +39,7 @@ public void performTest()
         private void exerciseEtsiTs102941DeltaCtlRequestId()
             throws Exception
         {
    -        ASN1Integer ctlSequence = new ASN1Integer(10);
    +        ASN1Integer ctlSequence = ASN1Integer.valueOf(10);
     
             Extension extension = new Extension(
                 Extension.etsiTs102941DeltaCtlRequestId,
    diff --git a/util/src/test/java/org/bouncycastle/oer/test/OERExpander.java b/util/src/test/java/org/bouncycastle/oer/test/OERExpander.java
    index 94cc3ded37..7f560a0ade 100644
    --- a/util/src/test/java/org/bouncycastle/oer/test/OERExpander.java
    +++ b/util/src/test/java/org/bouncycastle/oer/test/OERExpander.java
    @@ -687,7 +687,7 @@ public IntPopulate(Element def)
     
                     if (def.getLowerBound() == null && def.getUpperBound() == null)
                     {
    -                    script.add(new ASN1Integer(10)); // Unbounded so pick a value.
    +                    script.add(ASN1Integer.valueOf(10)); // Unbounded so pick a value.
                     }
                 }
     
    diff --git a/util/src/test/java/org/bouncycastle/oer/test/OERExtensionTest.java b/util/src/test/java/org/bouncycastle/oer/test/OERExtensionTest.java
    index ed40328bfa..9dff8c97b0 100644
    --- a/util/src/test/java/org/bouncycastle/oer/test/OERExtensionTest.java
    +++ b/util/src/test/java/org/bouncycastle/oer/test/OERExtensionTest.java
    @@ -36,7 +36,7 @@ public void testWithoutExtensionValue()
             Element ele = defBuilder.build();
     
             // Only has the non extension part populated
    -        ASN1Encodable withOutExtension = new DERSequence(new ASN1Encodable[]{new ASN1Integer(1)});
    +        ASN1Encodable withOutExtension = new DERSequence(ASN1Integer.ONE);
     
             byte[] raw = OEREncoder.toByteArray(withOutExtension, ele);
             TestCase.assertTrue((raw[0] & 0x80) == 0); // Extension present bit must be zero
    @@ -53,7 +53,7 @@ public void testWithOneExtensionValue()
             Element ele = defBuilder.build();
             {
                 // Only has the non extension part populated
    -            ASN1Encodable withOutExtension = new DERSequence(new ASN1Encodable[]{new ASN1Integer(1), new DERUTF8String("cats")});
    +            ASN1Encodable withOutExtension = new DERSequence(ASN1Integer.ONE, new DERUTF8String("cats"));
     
                 byte[] raw = OEREncoder.toByteArray(withOutExtension, ele);
                 TestCase.assertTrue((raw[0] & 0x80) != 0); // Extension present bit must be zero
    @@ -66,7 +66,7 @@ public void testWithOneExtensionValue()
             //
     
             {
    -            ASN1Encodable withOutExtension = new DERSequence(new ASN1Encodable[]{new ASN1Integer(1), OEROptional.ABSENT, new ASN1Integer(10)});
    +            ASN1Encodable withOutExtension = new DERSequence(new ASN1Encodable[]{ASN1Integer.ONE, OEROptional.ABSENT, ASN1Integer.valueOf(10)});
     
                 byte[] raw = OEREncoder.toByteArray(withOutExtension, ele);
                 TestCase.assertTrue((raw[0] & 0x80) != 0); // Extension present bit must be zero
    @@ -115,14 +115,13 @@ public void testSequenceWithUndefinedExtensions()
             Element writeElement = writeBuilder.build();
     
     
    -        ASN1Encodable enc = new DERSequence(new ASN1Encodable[]{
    +        ASN1Encodable enc = new DERSequence(
                 new DERSequence(new ASN1Encodable[]{
                     new DERUTF8String("cats"),
                     OEROptional.ABSENT, // this and the one below are actually extension values.
                     new DERUTF8String("other")
                 }),
    -            new ASN1Integer(10)
    -        });
    +            ASN1Integer.valueOf(10));
     
             byte[] value = OEREncoder.toByteArray(enc, writeElement);