Browse Source

Merge pull request #559 in CORE/base-third from bugfix/10.0 to feature/10.0

* commit '43c53d5affda4f7bb1c31fa2c75e73bcaf69c898':
  把bouncycastle1.64修改包名后升级原来的1.60
  把bouncycastle1.64修改包名后升级原来的1.60
research/11.0
superman 4 years ago
parent
commit
e192b7332e
  1. 6
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/LICENSE.java
  2. 44
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
  3. 96
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1BitString.java
  4. 103
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Boolean.java
  5. 142
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1EncodableVector.java
  6. 65
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Enumerated.java
  7. 292
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1External.java
  8. 162
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1GeneralizedTime.java
  9. 105
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1InputStream.java
  10. 164
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Integer.java
  11. 12
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Null.java
  12. 42
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Object.java
  13. 48
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
  14. 69
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1OctetString.java
  15. 263
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1OutputStream.java
  16. 24
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Primitive.java
  17. 222
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Sequence.java
  18. 414
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Set.java
  19. 33
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1StreamParser.java
  20. 87
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1TaggedObject.java
  21. 36
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1UTCTime.java
  22. 12
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERApplicationSpecific.java
  23. 14
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERFactory.java
  24. 33
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BEROctetString.java
  25. 11
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BEROctetStringGenerator.java
  26. 46
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BEROutputStream.java
  27. 46
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERSequence.java
  28. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERSequenceGenerator.java
  29. 55
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERSet.java
  30. 63
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERTaggedObject.java
  31. 45
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ConstructedOctetStream.java
  32. 35
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERApplicationSpecific.java
  33. 43
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERBMPString.java
  34. 46
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERBitString.java
  35. 22
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERBoolean.java
  36. 229
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERExternal.java
  37. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERExternalParser.java
  38. 14
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERFactory.java
  39. 7
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERGeneralString.java
  40. 16
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERGeneralizedTime.java
  41. 8
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERGraphicString.java
  42. 12
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERIA5String.java
  43. 6
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERNull.java
  44. 6
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERNumericString.java
  45. 23
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DEROctetString.java
  46. 24
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DEROutputStream.java
  47. 6
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERPrintableString.java
  48. 105
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSequence.java
  49. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSequenceGenerator.java
  50. 4
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSequenceParser.java
  51. 115
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSet.java
  52. 4
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSetParser.java
  53. 6
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERT61String.java
  54. 6
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERT61UTF8String.java
  55. 68
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERTaggedObject.java
  56. 5
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERUTF8String.java
  57. 16
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERUniversalString.java
  58. 8
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERVideotexString.java
  59. 6
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERVisibleString.java
  60. 124
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLApplicationSpecific.java
  61. 32
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLBitString.java
  62. 90
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLExternal.java
  63. 27
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLFactory.java
  64. 23
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLOutputStream.java
  65. 93
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSequence.java
  66. 12
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSequenceParser.java
  67. 91
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSet.java
  68. 12
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSetParser.java
  69. 67
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLTaggedObject.java
  70. 80
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DateUtil.java
  71. 12
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DefiniteLengthInputStream.java
  72. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/IndefiniteLengthInputStream.java
  73. 109
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/LazyEncodedSequence.java
  74. 12
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/LimitedInputStream.java
  75. 4
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/StreamUtil.java
  76. 18
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/anssi/ANSSINamedCurves.java
  77. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/anssi/ANSSIObjectIdentifiers.java
  78. 83
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
  79. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/EncryptedObjectStoreData.java
  80. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/EncryptedPrivateKeyData.java
  81. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/EncryptedSecretKeyData.java
  82. 126
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/LinkedCertificate.java
  83. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectData.java
  84. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectStore.java
  85. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectStoreData.java
  86. 20
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectStoreIntegrityCheck.java
  87. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/PbkdMacIntegrityCheck.java
  88. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/SecretKeyData.java
  89. 117
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/SignatureCheck.java
  90. 16
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bsi/BSIObjectIdentifiers.java
  91. 4
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCPublicationInfo.java
  92. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCStatusInfo.java
  93. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCStatusInfoV2.java
  94. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCUnsignedData.java
  95. 4
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CertificationRequest.java
  96. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/DecryptedPOP.java
  97. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/EncryptedPOP.java
  98. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/GetCRL.java
  99. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/GetCert.java
  100. 2
      fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/IdentityProofV2.java
  101. Some files were not shown because too many files have changed in this diff Show More

6
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/LICENSE.java

@ -5,7 +5,7 @@ import com.fr.third.org.bouncycastle.util.Strings;
/** /**
* The Bouncy Castle License * The Bouncy Castle License
* *
* Copyright (c) 2000-2017 The Legion Of The Bouncy Castle Inc. (http://www.bouncycastle.org) * Copyright (c) 2000-2019 The Legion Of The Bouncy Castle Inc. (http://www.bouncycastle.org)
* <p> * <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, * and associated documentation files (the "Software"), to deal in the Software without restriction,
@ -25,8 +25,8 @@ import com.fr.third.org.bouncycastle.util.Strings;
*/ */
public class LICENSE public class LICENSE
{ {
public static String licenseText = public static final String licenseText =
"Copyright (c) 2000-2017 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) " "Copyright (c) 2000-2019 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) "
+ Strings.lineSeparator() + Strings.lineSeparator()
+ Strings.lineSeparator() + Strings.lineSeparator()
+ "Permission is hereby granted, free of charge, to any person obtaining a copy of this software " + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software "

44
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1ApplicationSpecific.java

@ -3,6 +3,7 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import com.fr.third.org.bouncycastle.util.Arrays; import com.fr.third.org.bouncycastle.util.Arrays;
import com.fr.third.org.bouncycastle.util.encoders.Hex;
/** /**
* Base class for an ASN.1 ApplicationSpecific object * Base class for an ASN.1 ApplicationSpecific object
@ -153,15 +154,15 @@ public abstract class ASN1ApplicationSpecific
/* (non-Javadoc) /* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream) * @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream)
*/ */
void encode(ASN1OutputStream out) throws IOException void encode(ASN1OutputStream out, boolean withTag) throws IOException
{ {
int classBits = BERTags.APPLICATION; int flags = BERTags.APPLICATION;
if (isConstructed) if (isConstructed)
{ {
classBits |= BERTags.CONSTRUCTED; flags |= BERTags.CONSTRUCTED;
} }
out.writeEncoded(classBits, tag, octets); out.writeEncoded(withTag, flags, tag, octets);
} }
boolean asn1Equals( boolean asn1Equals(
@ -194,25 +195,19 @@ public abstract class ASN1ApplicationSpecific
// //
if (tagNo == 0x1f) if (tagNo == 0x1f)
{ {
tagNo = 0;
int b = input[index++] & 0xff; int b = input[index++] & 0xff;
// X.690-0207 8.1.2.4.2 // X.690-0207 8.1.2.4.2
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero." // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
if ((b & 0x7f) == 0) // Note: -1 will pass if ((b & 0x7f) == 0) // Note: -1 will pass
{ {
throw new ASN1ParsingException("corrupted stream - invalid high tag number found"); throw new IOException("corrupted stream - invalid high tag number found");
} }
while ((b >= 0) && ((b & 0x80) != 0)) while ((b & 0x80) != 0)
{ {
tagNo |= (b & 0x7f);
tagNo <<= 7;
b = input[index++] & 0xff; b = input[index++] & 0xff;
} }
// tagNo |= (b & 0x7f);
} }
byte[] tmp = new byte[input.length - index + 1]; byte[] tmp = new byte[input.length - index + 1];
@ -223,4 +218,29 @@ public abstract class ASN1ApplicationSpecific
return tmp; return tmp;
} }
public String toString()
{
StringBuffer sb = new StringBuffer();
sb.append("[");
if (isConstructed())
{
sb.append("CONSTRUCTED ");
}
sb.append("APPLICATION ");
sb.append(Integer.toString(getApplicationTag()));
sb.append("]");
// @todo content encoding somehow?
if (this.octets != null)
{
sb.append(" #");
sb.append(Hex.toHexString(this.octets));
}
else
{
sb.append(" #null");
}
sb.append(" ");
return sb.toString();
}
} }

96
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1BitString.java

@ -1,6 +1,5 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -58,6 +57,7 @@ public abstract class ASN1BitString
return 0; return 0;
} }
int bits = 1; int bits = 1;
while (((val <<= 1) & 0xFF) != 0) while (((val <<= 1) & 0xFF) != 0)
@ -99,6 +99,17 @@ public abstract class ASN1BitString
return result; return result;
} }
protected ASN1BitString(byte data, int padBits)
{
if (padBits > 7 || padBits < 0)
{
throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
}
this.data = new byte[]{ data };
this.padBits = padBits;
}
/** /**
* Base constructor. * Base constructor.
* *
@ -111,7 +122,7 @@ public abstract class ASN1BitString
{ {
if (data == null) if (data == null)
{ {
throw new NullPointerException("data cannot be null"); throw new NullPointerException("'data' cannot be null");
} }
if (data.length == 0 && padBits != 0) if (data.length == 0 && padBits != 0)
{ {
@ -134,20 +145,17 @@ public abstract class ASN1BitString
public String getString() public String getString()
{ {
StringBuffer buf = new StringBuffer("#"); StringBuffer buf = new StringBuffer("#");
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ASN1OutputStream aOut = new ASN1OutputStream(bOut);
byte[] string;
try try
{ {
aOut.writeObject(this); string = getEncoded();
} }
catch (IOException e) catch (IOException e)
{ {
throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e); throw new ASN1ParsingException("Internal error encoding BitString: " + e.getMessage(), e);
} }
byte[] string = bOut.toByteArray();
for (int i = 0; i != string.length; i++) for (int i = 0; i != string.length; i++)
{ {
buf.append(table[(string[i] >>> 4) & 0xf]); buf.append(table[(string[i] >>> 4) & 0xf]);
@ -163,18 +171,16 @@ public abstract class ASN1BitString
public int intValue() public int intValue()
{ {
int value = 0; int value = 0;
byte[] string = data; int end = Math.min(4, data.length - 1);
for (int i = 0; i < end; ++i)
if (padBits > 0 && data.length <= 4)
{ {
string = derForm(data, padBits); value |= (data[i] & 0xFF) << (8 * i);
} }
if (0 <= end && end < 4)
for (int i = 0; i != string.length && i != 4; i++)
{ {
value |= (string[i] & 0xff) << (8 * i); byte der = (byte)(data[end] & (0xFF << padBits));
value |= (der & 0xFF) << (8 * end);
} }
return value; return value;
} }
@ -212,10 +218,21 @@ public abstract class ASN1BitString
public int hashCode() public int hashCode()
{ {
return padBits ^ Arrays.hashCode(this.getBytes()); int end = data.length;
if (--end < 0)
{
return 1;
} }
protected boolean asn1Equals( byte der = (byte)(data[end] & (0xFF << padBits));
int hc = Arrays.hashCode(data, 0, end);
hc *= 257;
hc ^= der;
return hc ^ padBits;
}
boolean asn1Equals(
ASN1Primitive o) ASN1Primitive o)
{ {
if (!(o instanceof ASN1BitString)) if (!(o instanceof ASN1BitString))
@ -224,20 +241,46 @@ public abstract class ASN1BitString
} }
ASN1BitString other = (ASN1BitString)o; ASN1BitString other = (ASN1BitString)o;
if (padBits != other.padBits)
{
return false;
}
byte[] a = data, b = other.data;
int end = a.length;
if (end != b.length)
{
return false;
}
if (--end < 0)
{
return true;
}
for (int i = 0; i < end; ++i)
{
if (a[i] != b[i])
{
return false;
}
}
byte derA = (byte)(a[end] & (0xFF << padBits));
byte derB = (byte)(b[end] & (0xFF << padBits));
return this.padBits == other.padBits return derA == derB;
&& Arrays.areEqual(this.getBytes(), other.getBytes());
} }
/**
* @deprecated Will be hidden/removed.
*/
protected static byte[] derForm(byte[] data, int padBits) protected static byte[] derForm(byte[] data, int padBits)
{ {
byte[] rv = Arrays.clone(data); if (0 == data.length)
// DER requires pad bits be zero
if (padBits > 0)
{ {
rv[data.length - 1] &= 0xff << padBits; return data;
} }
byte[] rv = Arrays.clone(data);
// DER requires pad bits be zero
rv[data.length - 1] &= (0xFF << padBits);
return rv; return rv;
} }
@ -261,7 +304,7 @@ public abstract class ASN1BitString
if (padBits > 0 && padBits < 8) if (padBits > 0 && padBits < 8)
{ {
if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xff << padBits))) if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xFF << padBits)))
{ {
return new DLBitString(data, padBits); return new DLBitString(data, padBits);
} }
@ -286,6 +329,5 @@ public abstract class ASN1BitString
return new DLBitString(data, padBits); return new DLBitString(data, padBits);
} }
abstract void encode(ASN1OutputStream out) abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
throws IOException;
} }

103
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Boolean.java

@ -2,12 +2,10 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import com.fr.third.org.bouncycastle.util.Arrays;
/** /**
* Public facade of ASN.1 Boolean data. * Public facade of ASN.1 Boolean data.
* <p> * <p>
* Use following to place a new instance of ASN.1 Boolean in your dataset: * Use following to place a new instance of ASN.1 Boolean in your data:
* <ul> * <ul>
* <li> ASN1Boolean.TRUE literal</li> * <li> ASN1Boolean.TRUE literal</li>
* <li> ASN1Boolean.FALSE literal</li> * <li> ASN1Boolean.FALSE literal</li>
@ -18,13 +16,13 @@ import com.fr.third.org.bouncycastle.util.Arrays;
public class ASN1Boolean public class ASN1Boolean
extends ASN1Primitive extends ASN1Primitive
{ {
private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff }; private static final byte FALSE_VALUE = 0x00;
private static final byte[] FALSE_VALUE = new byte[] { 0 }; private static final byte TRUE_VALUE = (byte)0xFF;
private final byte[] value; public static final ASN1Boolean FALSE = new ASN1Boolean(FALSE_VALUE);
public static final ASN1Boolean TRUE = new ASN1Boolean(TRUE_VALUE);
public static final ASN1Boolean FALSE = new ASN1Boolean(false); private final byte value;
public static final ASN1Boolean TRUE = new ASN1Boolean(true);
/** /**
* Return a boolean from the passed in object. * Return a boolean from the passed in object.
@ -62,10 +60,9 @@ public class ASN1Boolean
* @param value true or false depending on the ASN1Boolean wanted. * @param value true or false depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance. * @return an ASN1Boolean instance.
*/ */
public static ASN1Boolean getInstance( public static ASN1Boolean getInstance(boolean value)
boolean value)
{ {
return (value ? TRUE : FALSE); return value ? TRUE : FALSE;
} }
/** /**
@ -73,10 +70,9 @@ public class ASN1Boolean
* @param value non-zero (true) or zero (false) depending on the ASN1Boolean wanted. * @param value non-zero (true) or zero (false) depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance. * @return an ASN1Boolean instance.
*/ */
public static ASN1Boolean getInstance( public static ASN1Boolean getInstance(int value)
int value)
{ {
return (value != 0 ? TRUE : FALSE); return value != 0 ? TRUE : FALSE;
} }
/** /**
@ -89,9 +85,7 @@ public class ASN1Boolean
* be converted. * be converted.
* @return an ASN1Boolean instance. * @return an ASN1Boolean instance.
*/ */
public static ASN1Boolean getInstance( public static ASN1Boolean getInstance(ASN1TaggedObject obj, boolean explicit)
ASN1TaggedObject obj,
boolean explicit)
{ {
ASN1Primitive o = obj.getObject(); ASN1Primitive o = obj.getObject();
@ -101,45 +95,18 @@ public class ASN1Boolean
} }
else else
{ {
return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets()); return ASN1Boolean.fromOctetString(ASN1OctetString.getInstance(o).getOctets());
}
}
ASN1Boolean(
byte[] value)
{
if (value.length != 1)
{
throw new IllegalArgumentException("byte value should have 1 byte in it");
}
if (value[0] == 0)
{
this.value = FALSE_VALUE;
}
else if ((value[0] & 0xff) == 0xff)
{
this.value = TRUE_VALUE;
}
else
{
this.value = Arrays.clone(value);
} }
} }
/** private ASN1Boolean(byte value)
* @deprecated use getInstance(boolean) method.
* @param value true or false.
*/
public ASN1Boolean(
boolean value)
{ {
this.value = (value) ? TRUE_VALUE : FALSE_VALUE; this.value = value;
} }
public boolean isTrue() public boolean isTrue()
{ {
return (value[0] != 0); return value != FALSE_VALUE;
} }
boolean isConstructed() boolean isConstructed()
@ -152,33 +119,36 @@ public class ASN1Boolean
return 3; return 3;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.BOOLEAN, value); out.writeEncoded(withTag, BERTags.BOOLEAN, value);
} }
protected boolean asn1Equals( boolean asn1Equals(ASN1Primitive other)
ASN1Primitive o)
{ {
if (o instanceof ASN1Boolean) if (!(other instanceof ASN1Boolean))
{ {
return (value[0] == ((ASN1Boolean)o).value[0]); return false;
} }
return false; ASN1Boolean that = (ASN1Boolean)other;
return this.isTrue() == that.isTrue();
} }
public int hashCode() public int hashCode()
{ {
return value[0]; return isTrue() ? 1 : 0;
} }
ASN1Primitive toDERObject()
{
return isTrue() ? TRUE : FALSE;
}
public String toString() public String toString()
{ {
return (value[0] != 0) ? "TRUE" : "FALSE"; return isTrue() ? "TRUE" : "FALSE";
} }
static ASN1Boolean fromOctetString(byte[] value) static ASN1Boolean fromOctetString(byte[] value)
@ -188,17 +158,12 @@ public class ASN1Boolean
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it"); throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
} }
if (value[0] == 0) byte b = value[0];
{ switch (b)
return FALSE;
}
else if ((value[0] & 0xff) == 0xff)
{
return TRUE;
}
else
{ {
return new ASN1Boolean(value); case FALSE_VALUE: return FALSE;
case TRUE_VALUE: return TRUE;
default: return new ASN1Boolean(b);
} }
} }
} }

142
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1EncodableVector.java

@ -1,43 +1,87 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.util.Enumeration;
import java.util.Vector;
/** /**
* Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs. * Mutable class for building ASN.1 constructed objects such as SETs or SEQUENCEs.
*/ */
public class ASN1EncodableVector public class ASN1EncodableVector
{ {
private final Vector v = new Vector(); static final ASN1Encodable[] EMPTY_ELEMENTS = new ASN1Encodable[0];
private static final int DEFAULT_CAPACITY = 10;
private ASN1Encodable[] elements;
private int elementCount;
private boolean copyOnWrite;
/**
* Base constructor.
*/
public ASN1EncodableVector() public ASN1EncodableVector()
{ {
this(DEFAULT_CAPACITY);
} }
/** public ASN1EncodableVector(int initialCapacity)
* Add an encodable to the vector.
*
* @param obj the encodable to add.
*/
public void add(ASN1Encodable obj)
{ {
v.addElement(obj); if (initialCapacity < 0)
{
throw new IllegalArgumentException("'initialCapacity' must not be negative");
}
this.elements = (initialCapacity == 0) ? EMPTY_ELEMENTS : new ASN1Encodable[initialCapacity];
this.elementCount = 0;
this.copyOnWrite = false;
}
public void add(ASN1Encodable element)
{
if (null == element)
{
throw new NullPointerException("'element' cannot be null");
}
int capacity = elements.length;
int minCapacity = elementCount + 1;
if ((minCapacity > capacity) | copyOnWrite)
{
reallocate(minCapacity);
}
this.elements[elementCount] = element;
this.elementCount = minCapacity;
} }
/**
* Add the contents of another vector.
*
* @param other the vector to add.
*/
public void addAll(ASN1EncodableVector other) public void addAll(ASN1EncodableVector other)
{ {
for (Enumeration en = other.v.elements(); en.hasMoreElements();) if (null == other)
{
throw new NullPointerException("'other' cannot be null");
}
int otherElementCount = other.size();
if (otherElementCount < 1)
{
return;
}
int capacity = elements.length;
int minCapacity = elementCount + otherElementCount;
if ((minCapacity > capacity) | copyOnWrite)
{
reallocate(minCapacity);
}
int i = 0;
do
{
ASN1Encodable otherElement = other.get(i);
if (null == otherElement)
{ {
v.addElement(en.nextElement()); throw new NullPointerException("'other' elements cannot be null");
}
this.elements[elementCount + i] = otherElement;
} }
while (++i < otherElementCount);
this.elementCount = minCapacity;
} }
/** /**
@ -48,7 +92,12 @@ public class ASN1EncodableVector
*/ */
public ASN1Encodable get(int i) public ASN1Encodable get(int i)
{ {
return (ASN1Encodable)v.elementAt(i); if (i >= elementCount)
{
throw new ArrayIndexOutOfBoundsException(i + " >= " + elementCount);
}
return elements[i];
} }
/** /**
@ -58,6 +107,53 @@ public class ASN1EncodableVector
*/ */
public int size() public int size()
{ {
return v.size(); return elementCount;
}
ASN1Encodable[] copyElements()
{
if (0 == elementCount)
{
return EMPTY_ELEMENTS;
}
ASN1Encodable[] copy = new ASN1Encodable[elementCount];
System.arraycopy(elements, 0, copy, 0, elementCount);
return copy;
}
ASN1Encodable[] takeElements()
{
if (0 == elementCount)
{
return EMPTY_ELEMENTS;
}
if (elements.length == elementCount)
{
this.copyOnWrite = true;
return elements;
}
ASN1Encodable[] copy = new ASN1Encodable[elementCount];
System.arraycopy(elements, 0, copy, 0, elementCount);
return copy;
}
private void reallocate(int minCapacity)
{
int oldCapacity = elements.length;
int newCapacity = Math.max(oldCapacity, minCapacity + (minCapacity >> 1));
ASN1Encodable[] copy = new ASN1Encodable[newCapacity];
System.arraycopy(elements, 0, copy, 0, elementCount);
this.elements = copy;
this.copyOnWrite = false;
}
static ASN1Encodable[] cloneElements(ASN1Encodable[] elements)
{
return elements.length < 1 ? EMPTY_ELEMENTS : (ASN1Encodable[])elements.clone();
} }
} }

65
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Enumerated.java

@ -4,7 +4,6 @@ import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import com.fr.third.org.bouncycastle.util.Arrays; import com.fr.third.org.bouncycastle.util.Arrays;
import com.fr.third.org.bouncycastle.util.Properties;
/** /**
* Class representing the ASN.1 ENUMERATED type. * Class representing the ASN.1 ENUMERATED type.
@ -13,6 +12,7 @@ public class ASN1Enumerated
extends ASN1Primitive extends ASN1Primitive
{ {
private final byte[] bytes; private final byte[] bytes;
private final int start;
/** /**
* return an enumerated from the passed in object * return an enumerated from the passed in object
@ -66,7 +66,7 @@ public class ASN1Enumerated
} }
else else
{ {
return fromOctetString(((ASN1OctetString)o).getOctets()); return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -75,10 +75,15 @@ public class ASN1Enumerated
* *
* @param value the value of this enumerated. * @param value the value of this enumerated.
*/ */
public ASN1Enumerated( public ASN1Enumerated(int value)
int value)
{ {
bytes = BigInteger.valueOf(value).toByteArray(); if (value < 0)
{
throw new IllegalArgumentException("enumerated must be non-negative");
}
this.bytes = BigInteger.valueOf(value).toByteArray();
this.start = 0;
} }
/** /**
@ -86,10 +91,15 @@ public class ASN1Enumerated
* *
* @param value the value of this enumerated. * @param value the value of this enumerated.
*/ */
public ASN1Enumerated( public ASN1Enumerated(BigInteger value)
BigInteger value)
{ {
bytes = value.toByteArray(); if (value.signum() < 0)
{
throw new IllegalArgumentException("enumerated must be non-negative");
}
this.bytes = value.toByteArray();
this.start = 0;
} }
/** /**
@ -97,17 +107,19 @@ public class ASN1Enumerated
* *
* @param bytes the value of this enumerated as an encoded BigInteger (signed). * @param bytes the value of this enumerated as an encoded BigInteger (signed).
*/ */
public ASN1Enumerated( public ASN1Enumerated(byte[] bytes)
byte[] bytes)
{
if (!Properties.isOverrideSet("com.fr.third.org.bouncycastle.asn1.allow_unsafe_integer"))
{ {
if (ASN1Integer.isMalformed(bytes)) if (ASN1Integer.isMalformed(bytes))
{ {
throw new IllegalArgumentException("malformed enumerated"); throw new IllegalArgumentException("malformed enumerated");
} }
if (0 != (bytes[0] & 0x80))
{
throw new IllegalArgumentException("enumerated must be non-negative");
} }
this.bytes = Arrays.clone(bytes); this.bytes = Arrays.clone(bytes);
this.start = ASN1Integer.signBytesToSkip(bytes);
} }
public BigInteger getValue() public BigInteger getValue()
@ -115,6 +127,25 @@ public class ASN1Enumerated
return new BigInteger(bytes); return new BigInteger(bytes);
} }
public boolean hasValue(BigInteger x)
{
return null != x
// Fast check to avoid allocation
&& ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED) == x.intValue()
&& getValue().equals(x);
}
public int intValueExact()
{
int count = bytes.length - start;
if (count > 4)
{
throw new ArithmeticException("ASN.1 Enumerated out of int range");
}
return ASN1Integer.intValue(bytes, start, ASN1Integer.SIGN_EXT_SIGNED);
}
boolean isConstructed() boolean isConstructed()
{ {
return false; return false;
@ -125,11 +156,9 @@ public class ASN1Enumerated
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length; return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.ENUMERATED, bytes); out.writeEncoded(withTag, BERTags.ENUMERATED, bytes);
} }
boolean asn1Equals( boolean asn1Equals(
@ -167,14 +196,14 @@ public class ASN1Enumerated
if (value >= cache.length) if (value >= cache.length)
{ {
return new ASN1Enumerated(Arrays.clone(enc)); return new ASN1Enumerated(enc);
} }
ASN1Enumerated possibleMatch = cache[value]; ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null) if (possibleMatch == null)
{ {
possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc)); possibleMatch = cache[value] = new ASN1Enumerated(enc);
} }
return possibleMatch; return possibleMatch;

292
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1External.java

@ -0,0 +1,292 @@
package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException;
/**
* Class representing the DER-type External
*/
public abstract class ASN1External
extends ASN1Primitive
{
protected ASN1ObjectIdentifier directReference;
protected ASN1Integer indirectReference;
protected ASN1Primitive dataValueDescriptor;
protected int encoding;
protected ASN1Primitive externalContent;
/**
* Construct an EXTERNAL object, the input encoding vector must have exactly two elements on it.
* <p>
* Acceptable input formats are:
* <ul>
* <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
* <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
* @throws IllegalArgumentException if input size is wrong, or
*/
public ASN1External(ASN1EncodableVector vector)
{
int offset = 0;
ASN1Primitive enc = getObjFromVector(vector, offset);
if (enc instanceof ASN1ObjectIdentifier)
{
directReference = (ASN1ObjectIdentifier)enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (enc instanceof ASN1Integer)
{
indirectReference = (ASN1Integer) enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (!(enc instanceof ASN1TaggedObject))
{
dataValueDescriptor = (ASN1Primitive) enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (vector.size() != offset + 1)
{
throw new IllegalArgumentException("input vector too large");
}
if (!(enc instanceof ASN1TaggedObject))
{
throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
}
ASN1TaggedObject obj = (ASN1TaggedObject)enc;
setEncoding(obj.getTagNo());
externalContent = obj.getObject();
}
private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
{
if (v.size() <= index)
{
throw new IllegalArgumentException("too few objects in input vector");
}
return v.get(index).toASN1Primitive();
}
/**
* Creates a new instance of External
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
}
/**
* Creates a new instance of External.
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
public ASN1External(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
setDirectReference(directReference);
setIndirectReference(indirectReference);
setDataValueDescriptor(dataValueDescriptor);
setEncoding(encoding);
setExternalContent(externalData.toASN1Primitive());
}
ASN1Primitive toDERObject()
{
return new DERExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
}
ASN1Primitive toDLObject()
{
return new DLExternal(directReference, indirectReference, dataValueDescriptor, encoding, externalContent);
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode()
{
int ret = 0;
if (directReference != null)
{
ret = directReference.hashCode();
}
if (indirectReference != null)
{
ret ^= indirectReference.hashCode();
}
if (dataValueDescriptor != null)
{
ret ^= dataValueDescriptor.hashCode();
}
ret ^= externalContent.hashCode();
return ret;
}
boolean isConstructed()
{
return true;
}
int encodedLength()
throws IOException
{
return this.getEncoded().length;
}
/* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#asn1Equals(com.fr.third.org.bouncycastle.asn1.ASN1Primitive)
*/
boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof ASN1External))
{
return false;
}
if (this == o)
{
return true;
}
ASN1External other = (ASN1External)o;
if (directReference != null)
{
if (other.directReference == null || !other.directReference.equals(directReference))
{
return false;
}
}
if (indirectReference != null)
{
if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
{
return false;
}
}
if (dataValueDescriptor != null)
{
if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
{
return false;
}
}
return externalContent.equals(other.externalContent);
}
/**
* Returns the data value descriptor
* @return The descriptor
*/
public ASN1Primitive getDataValueDescriptor()
{
return dataValueDescriptor;
}
/**
* Returns the direct reference of the external element
* @return The reference
*/
public ASN1ObjectIdentifier getDirectReference()
{
return directReference;
}
/**
* Returns the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
* @return The encoding
*/
public int getEncoding()
{
return encoding;
}
/**
* Returns the content of this element
* @return The content
*/
public ASN1Primitive getExternalContent()
{
return externalContent;
}
/**
* Returns the indirect reference of this element
* @return The reference
*/
public ASN1Integer getIndirectReference()
{
return indirectReference;
}
/**
* Sets the data value descriptor
* @param dataValueDescriptor The descriptor
*/
private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
{
this.dataValueDescriptor = dataValueDescriptor;
}
/**
* Sets the direct reference of the external element
* @param directReferemce The reference
*/
private void setDirectReference(ASN1ObjectIdentifier directReferemce)
{
this.directReference = directReferemce;
}
/**
* Sets the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
* @param encoding The encoding
*/
private void setEncoding(int encoding)
{
if (encoding < 0 || encoding > 2)
{
throw new IllegalArgumentException("invalid encoding value: " + encoding);
}
this.encoding = encoding;
}
/**
* Sets the content of this element
* @param externalContent The content
*/
private void setExternalContent(ASN1Primitive externalContent)
{
this.externalContent = externalContent;
}
/**
* Sets the indirect reference of this element
* @param indirectReference The reference
*/
private void setIndirectReference(ASN1Integer indirectReference)
{
this.indirectReference = indirectReference;
}
}

162
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1GeneralizedTime.java

@ -98,7 +98,7 @@ public class ASN1GeneralizedTime
} }
else else
{ {
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets()); return new ASN1GeneralizedTime(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -133,7 +133,7 @@ public class ASN1GeneralizedTime
public ASN1GeneralizedTime( public ASN1GeneralizedTime(
Date time) Date time)
{ {
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", DateUtil.EN_Locale);
dateF.setTimeZone(new SimpleTimeZone(0, "Z")); dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
@ -161,7 +161,16 @@ public class ASN1GeneralizedTime
ASN1GeneralizedTime( ASN1GeneralizedTime(
byte[] bytes) byte[] bytes)
{ {
if (bytes.length < 4)
{
throw new IllegalArgumentException("GeneralizedTime string too short");
}
this.time = bytes; this.time = bytes;
if (!(isDigit(0) && isDigit(1) && isDigit(2) && isDigit(3)))
{
throw new IllegalArgumentException("illegal characters in GeneralizedTime string");
}
} }
/** /**
@ -200,8 +209,16 @@ public class ASN1GeneralizedTime
} }
else else
{ {
int signPos = stime.length() - 5; int signPos = stime.length() - 6;
char sign = stime.charAt(signPos); char sign = stime.charAt(signPos);
if ((sign == '-' || sign == '+') && stime.indexOf("GMT") == signPos - 3)
{
// already a GMT string!
return stime;
}
signPos = stime.length() - 5;
sign = stime.charAt(signPos);
if (sign == '-' || sign == '+') if (sign == '-' || sign == '+')
{ {
return stime.substring(0, signPos) return stime.substring(0, signPos)
@ -210,8 +227,7 @@ public class ASN1GeneralizedTime
+ ":" + ":"
+ stime.substring(signPos + 3); + stime.substring(signPos + 3);
} }
else
{
signPos = stime.length() - 3; signPos = stime.length() - 3;
sign = stime.charAt(signPos); sign = stime.charAt(signPos);
if (sign == '-' || sign == '+') if (sign == '-' || sign == '+')
@ -222,11 +238,10 @@ public class ASN1GeneralizedTime
+ ":00"; + ":00";
} }
} }
} return stime + calculateGMTOffset(stime);
return stime + calculateGMTOffset();
} }
private String calculateGMTOffset() private String calculateGMTOffset(String stime)
{ {
String sign = "+"; String sign = "+";
TimeZone timeZone = TimeZone.getDefault(); TimeZone timeZone = TimeZone.getDefault();
@ -241,19 +256,86 @@ public class ASN1GeneralizedTime
try try
{ {
if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) if (timeZone.useDaylightTime())
{
if (hasFractionalSeconds())
{
stime = pruneFractionalSeconds(stime);
}
SimpleDateFormat dateF = calculateGMTDateFormat();
if (timeZone.inDaylightTime(
dateF.parse(stime + "GMT" + sign + convert(hours) + ":" + convert(minutes))))
{ {
hours += sign.equals("+") ? 1 : -1; hours += sign.equals("+") ? 1 : -1;
} }
} }
}
catch (ParseException e) catch (ParseException e)
{ { e.printStackTrace();
// we'll do our best and ignore daylight savings // we'll do our best and ignore daylight savings
} }
return "GMT" + sign + convert(hours) + ":" + convert(minutes); return "GMT" + sign + convert(hours) + ":" + convert(minutes);
} }
private SimpleDateFormat calculateGMTDateFormat()
{
SimpleDateFormat dateF;
if (hasFractionalSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
}
else if (hasSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
}
else if (hasMinutes())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmz");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHz");
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
return dateF;
}
private String pruneFractionalSeconds(String origTime)
{
// java misinterprets extra digits as being milliseconds...
String frac = origTime.substring(14);
int index;
for (index = 1; index < frac.length(); index++)
{
char ch = frac.charAt(index);
if (!('0' <= ch && ch <= '9'))
{
break;
}
}
if (index - 1 > 3)
{
frac = frac.substring(0, 4) + frac.substring(index);
origTime = origTime.substring(0, 14) + frac;
}
else if (index - 1 == 1)
{
frac = frac.substring(0, index) + "00" + frac.substring(index);
origTime = origTime.substring(0, 14) + frac;
}
else if (index - 1 == 2)
{
frac = frac.substring(0, index) + "0" + frac.substring(index);
origTime = origTime.substring(0, 14) + frac;
}
return origTime;
}
private String convert(int time) private String convert(int time)
{ {
if (time < 10) if (time < 10)
@ -295,24 +377,7 @@ public class ASN1GeneralizedTime
else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0) else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
{ {
d = this.getTime(); d = this.getTime();
if (hasFractionalSeconds()) dateF = calculateGMTDateFormat();
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
}
else if (hasSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
}
else if (hasMinutes())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmz");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHz");
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
} }
else else
{ {
@ -338,36 +403,10 @@ public class ASN1GeneralizedTime
if (hasFractionalSeconds()) if (hasFractionalSeconds())
{ {
// java misinterprets extra digits as being milliseconds... d = pruneFractionalSeconds(d);
String frac = d.substring(14);
int index;
for (index = 1; index < frac.length(); index++)
{
char ch = frac.charAt(index);
if (!('0' <= ch && ch <= '9'))
{
break;
}
}
if (index - 1 > 3)
{
frac = frac.substring(0, 4) + frac.substring(index);
d = d.substring(0, 14) + frac;
}
else if (index - 1 == 1)
{
frac = frac.substring(0, index) + "00" + frac.substring(index);
d = d.substring(0, 14) + frac;
}
else if (index - 1 == 2)
{
frac = frac.substring(0, index) + "0" + frac.substring(index);
d = d.substring(0, 14) + frac;
}
} }
return dateF.parse(d); return DateUtil.epochAdjust(dateF.parse(d));
} }
protected boolean hasFractionalSeconds() protected boolean hasFractionalSeconds()
@ -412,11 +451,9 @@ public class ASN1GeneralizedTime
return 1 + StreamUtil.calculateBodyLength(length) + length; return 1 + StreamUtil.calculateBodyLength(length) + length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.GENERALIZED_TIME, time); out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, time);
} }
ASN1Primitive toDERObject() ASN1Primitive toDERObject()
@ -424,6 +461,11 @@ public class ASN1GeneralizedTime
return new DERGeneralizedTime(time); return new DERGeneralizedTime(time);
} }
ASN1Primitive toDLObject()
{
return new DERGeneralizedTime(time);
}
boolean asn1Equals( boolean asn1Equals(
ASN1Primitive o) ASN1Primitive o)
{ {

105
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1InputStream.java

@ -109,7 +109,7 @@ public class ASN1InputStream
protected int readLength() protected int readLength()
throws IOException throws IOException
{ {
return readLength(this, limit); return readLength(this, limit, false);
} }
protected void readFully( protected void readFully(
@ -139,11 +139,11 @@ public class ASN1InputStream
{ {
boolean isConstructed = (tag & CONSTRUCTED) != 0; boolean isConstructed = (tag & CONSTRUCTED) != 0;
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length); DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length, limit);
if ((tag & APPLICATION) != 0) if ((tag & APPLICATION) != 0)
{ {
return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
} }
if ((tag & TAGGED) != 0) if ((tag & TAGGED) != 0)
@ -160,12 +160,20 @@ public class ASN1InputStream
// //
// yes, people actually do this... // yes, people actually do this...
// //
ASN1EncodableVector v = buildDEREncodableVector(defIn); ASN1EncodableVector v = readVector(defIn);
ASN1OctetString[] strings = new ASN1OctetString[v.size()]; ASN1OctetString[] strings = new ASN1OctetString[v.size()];
for (int i = 0; i != strings.length; i++) for (int i = 0; i != strings.length; i++)
{ {
strings[i] = (ASN1OctetString)v.get(i); ASN1Encodable asn1Obj = v.get(i);
if (asn1Obj instanceof ASN1OctetString)
{
strings[i] = (ASN1OctetString)asn1Obj;
}
else
{
throw new ASN1Exception("unknown object encountered in constructed OCTET STRING: " + asn1Obj.getClass());
}
} }
return new BEROctetString(strings); return new BEROctetString(strings);
@ -176,12 +184,12 @@ public class ASN1InputStream
} }
else else
{ {
return DERFactory.createSequence(buildDEREncodableVector(defIn)); return DLFactory.createSequence(readVector(defIn));
} }
case SET: case SET:
return DERFactory.createSet(buildDEREncodableVector(defIn)); return DLFactory.createSet(readVector(defIn));
case EXTERNAL: case EXTERNAL:
return new DERExternal(buildDEREncodableVector(defIn)); return new DLExternal(readVector(defIn));
default: default:
throw new IOException("unknown tag " + tagNo + " encountered"); throw new IOException("unknown tag " + tagNo + " encountered");
} }
@ -190,24 +198,21 @@ public class ASN1InputStream
return createPrimitiveDERObject(tagNo, defIn, tmpBuffers); return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
} }
ASN1EncodableVector buildEncodableVector() ASN1EncodableVector readVector(DefiniteLengthInputStream dIn) throws IOException
throws IOException
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); if (dIn.getRemaining() < 1)
ASN1Primitive o;
while ((o = readObject()) != null)
{ {
v.add(o); return new ASN1EncodableVector(0);
}
return v;
} }
ASN1EncodableVector buildDEREncodableVector( ASN1InputStream subStream = new ASN1InputStream(dIn);
DefiniteLengthInputStream dIn) throws IOException ASN1EncodableVector v = new ASN1EncodableVector();
ASN1Primitive p;
while ((p = subStream.readObject()) != null)
{ {
return new ASN1InputStream(dIn).buildEncodableVector(); v.add(p);
}
return v;
} }
public ASN1Primitive readObject() public ASN1Primitive readObject()
@ -323,7 +328,7 @@ public class ASN1InputStream
return tagNo; return tagNo;
} }
static int readLength(InputStream s, int limit) static int readLength(InputStream s, int limit, boolean isParsing)
throws IOException throws IOException
{ {
int length = s.read(); int length = s.read();
@ -365,9 +370,9 @@ public class ASN1InputStream
throw new IOException("corrupted stream - negative length found"); throw new IOException("corrupted stream - negative length found");
} }
if (length >= limit) // after all we must have read at least 1 byte if (length >= limit && !isParsing) // after all we must have read at least 1 byte
{ {
throw new IOException("corrupted stream - out of bounds length found"); throw new IOException("corrupted stream - out of bounds length found: " + length + " >= " + limit);
} }
} }
@ -400,25 +405,53 @@ public class ASN1InputStream
private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn) private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn)
throws IOException throws IOException
{ {
int len = defIn.getRemaining() / 2; int remainingBytes = defIn.getRemaining();
char[] buf = new char[len]; if (0 != (remainingBytes & 1))
int totalRead = 0;
while (totalRead < len)
{ {
int ch1 = defIn.read(); throw new IOException("malformed BMPString encoding encountered");
if (ch1 < 0) }
char[] string = new char[remainingBytes / 2];
int stringPos = 0;
byte[] buf = new byte[8];
while (remainingBytes >= 8)
{
if (Streams.readFully(defIn, buf, 0, 8) != 8)
{
throw new EOFException("EOF encountered in middle of BMPString");
}
string[stringPos ] = (char)((buf[0] << 8) | (buf[1] & 0xFF));
string[stringPos + 1] = (char)((buf[2] << 8) | (buf[3] & 0xFF));
string[stringPos + 2] = (char)((buf[4] << 8) | (buf[5] & 0xFF));
string[stringPos + 3] = (char)((buf[6] << 8) | (buf[7] & 0xFF));
stringPos += 4;
remainingBytes -= 8;
}
if (remainingBytes > 0)
{
if (Streams.readFully(defIn, buf, 0, remainingBytes) != remainingBytes)
{ {
break; throw new EOFException("EOF encountered in middle of BMPString");
} }
int ch2 = defIn.read();
if (ch2 < 0) int bufPos = 0;
do
{ {
break; int b1 = buf[bufPos++] << 8;
int b2 = buf[bufPos++] & 0xFF;
string[stringPos++] = (char)(b1 | b2);
} }
buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff)); while (bufPos < remainingBytes);
} }
return buf; if (0 != defIn.getRemaining() || string.length != stringPos)
{
throw new IllegalStateException();
}
return string;
} }
static ASN1Primitive createPrimitiveDERObject( static ASN1Primitive createPrimitiveDERObject(

164
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Integer.java

@ -12,7 +12,11 @@ import com.fr.third.org.bouncycastle.util.Properties;
public class ASN1Integer public class ASN1Integer
extends ASN1Primitive extends ASN1Primitive
{ {
static final int SIGN_EXT_SIGNED = 0xFFFFFFFF;
static final int SIGN_EXT_UNSIGNED = 0xFF;
private final byte[] bytes; private final byte[] bytes;
private final int start;
/** /**
* Return an integer from the passed in object. * Return an integer from the passed in object.
@ -75,10 +79,10 @@ public class ASN1Integer
* *
* @param value the long representing the value desired. * @param value the long representing the value desired.
*/ */
public ASN1Integer( public ASN1Integer(long value)
long value)
{ {
bytes = BigInteger.valueOf(value).toByteArray(); this.bytes = BigInteger.valueOf(value).toByteArray();
this.start = 0;
} }
/** /**
@ -86,10 +90,10 @@ public class ASN1Integer
* *
* @param value the BigInteger representing the value desired. * @param value the BigInteger representing the value desired.
*/ */
public ASN1Integer( public ASN1Integer(BigInteger value)
BigInteger value)
{ {
bytes = value.toByteArray(); this.bytes = value.toByteArray();
this.start = 0;
} }
/** /**
@ -114,62 +118,77 @@ public class ASN1Integer
* *
* @param bytes the byte array representing a 2's complement encoding of a BigInteger. * @param bytes the byte array representing a 2's complement encoding of a BigInteger.
*/ */
public ASN1Integer( public ASN1Integer(byte[] bytes)
byte[] bytes)
{ {
this(bytes, true); this(bytes, true);
} }
ASN1Integer(byte[] bytes, boolean clone) ASN1Integer(byte[] bytes, boolean clone)
{
// Apply loose validation, see note in public constructor ANS1Integer(byte[])
if (!Properties.isOverrideSet("com.fr.third.org.bouncycastle.asn1.allow_unsafe_integer"))
{ {
if (isMalformed(bytes)) if (isMalformed(bytes))
{ {
throw new IllegalArgumentException("malformed integer"); throw new IllegalArgumentException("malformed integer");
} }
}
this.bytes = (clone) ? Arrays.clone(bytes) : bytes; this.bytes = clone ? Arrays.clone(bytes) : bytes;
this.start = signBytesToSkip(bytes);
} }
/** /**
* Apply the correct validation for an INTEGER primitive following the BER rules. * in some cases positive values get crammed into a space,
* that's not quite big enough...
* *
* @param bytes The raw encoding of the integer. * @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
* @return true if the (in)put fails this validation.
*/ */
static boolean isMalformed(byte[] bytes) public BigInteger getPositiveValue()
{
if (bytes.length > 1)
{ {
if (bytes[0] == 0 && (bytes[1] & 0x80) == 0) return new BigInteger(1, bytes);
}
public BigInteger getValue()
{ {
return true; return new BigInteger(bytes);
} }
if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
public boolean hasValue(BigInteger x)
{ {
return true; return null != x
// Fast check to avoid allocation
&& intValue(bytes, start, SIGN_EXT_SIGNED) == x.intValue()
&& getValue().equals(x);
} }
public int intPositiveValueExact()
{
int count = bytes.length - start;
if (count > 4 || (count == 4 && 0 != (bytes[start] & 0x80)))
{
throw new ArithmeticException("ASN.1 Integer out of positive int range");
} }
return false; return intValue(bytes, start, SIGN_EXT_UNSIGNED);
} }
public BigInteger getValue() public int intValueExact()
{ {
return new BigInteger(bytes); int count = bytes.length - start;
if (count > 4)
{
throw new ArithmeticException("ASN.1 Integer out of int range");
} }
/** return intValue(bytes, start, SIGN_EXT_SIGNED);
* in some cases positive values get crammed into a space, }
* that's not quite big enough...
* public long longValueExact()
* @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
*/
public BigInteger getPositiveValue()
{ {
return new BigInteger(1, bytes); int count = bytes.length - start;
if (count > 8)
{
throw new ArithmeticException("ASN.1 Integer out of long range");
}
return longValue(bytes, start, SIGN_EXT_SIGNED);
} }
boolean isConstructed() boolean isConstructed()
@ -182,27 +201,17 @@ public class ASN1Integer
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length; return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.INTEGER, bytes); out.writeEncoded(withTag, BERTags.INTEGER, bytes);
} }
public int hashCode() public int hashCode()
{ {
int value = 0; return Arrays.hashCode(bytes);
for (int i = 0; i != bytes.length; i++)
{
value ^= (bytes[i] & 0xff) << (i % 4);
} }
return value; boolean asn1Equals(ASN1Primitive o)
}
boolean asn1Equals(
ASN1Primitive o)
{ {
if (!(o instanceof ASN1Integer)) if (!(o instanceof ASN1Integer))
{ {
@ -211,7 +220,7 @@ public class ASN1Integer
ASN1Integer other = (ASN1Integer)o; ASN1Integer other = (ASN1Integer)o;
return Arrays.areEqual(bytes, other.bytes); return Arrays.areEqual(this.bytes, other.bytes);
} }
public String toString() public String toString()
@ -219,4 +228,61 @@ public class ASN1Integer
return getValue().toString(); return getValue().toString();
} }
static int intValue(byte[] bytes, int start, int signExt)
{
int length = bytes.length;
int pos = Math.max(start, length - 4);
int val = bytes[pos] & signExt;
while (++pos < length)
{
val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
}
return val;
}
static long longValue(byte[] bytes, int start, int signExt)
{
int length = bytes.length;
int pos = Math.max(start, length - 8);
long val = bytes[pos] & signExt;
while (++pos < length)
{
val = (val << 8) | (bytes[pos] & SIGN_EXT_UNSIGNED);
}
return val;
}
/**
* Apply the correct validation for an INTEGER primitive following the BER rules.
*
* @param bytes The raw encoding of the integer.
* @return true if the (in)put fails this validation.
*/
static boolean isMalformed(byte[] bytes)
{
switch (bytes.length)
{
case 0:
return true;
case 1:
return false;
default:
return bytes[0] == (bytes[1] >> 7)
// Apply loose validation, see note in public constructor ASN1Integer(byte[])
&& !Properties.isOverrideSet("com.fr.third.org.bouncycastle.asn1.allow_unsafe_integer");
}
}
static int signBytesToSkip(byte[] bytes)
{
int pos = 0, last = bytes.length - 1;
while (pos < last
&& bytes[pos] == (bytes[pos + 1] >> 7))
{
++pos;
}
return pos;
}
} }

12
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Null.java

@ -1,3 +1,6 @@
/***************************************************************/
/****** DO NOT EDIT THIS CLASS bc-java SOURCE FILE ******/
/***************************************************************/
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
@ -8,6 +11,11 @@ import java.io.IOException;
public abstract class ASN1Null public abstract class ASN1Null
extends ASN1Primitive extends ASN1Primitive
{ {
ASN1Null()
{
}
/** /**
* Return an instance of ASN.1 NULL from the passed in object. * Return an instance of ASN.1 NULL from the passed in object.
* <p> * <p>
@ -17,6 +25,7 @@ public abstract class ASN1Null
* <li> {@link ASN1Null} object * <li> {@link ASN1Null} object
* <li> a byte[] containing ASN.1 NULL object * <li> a byte[] containing ASN.1 NULL object
* </ul> * </ul>
* </p>
* *
* @param o object to be converted. * @param o object to be converted.
* @return an instance of ASN1Null, or null. * @return an instance of ASN1Null, or null.
@ -64,8 +73,7 @@ public abstract class ASN1Null
return true; return true;
} }
abstract void encode(ASN1OutputStream out) abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
throws IOException;
public String toString() public String toString()
{ {

42
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Object.java

@ -2,6 +2,7 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import com.fr.third.org.bouncycastle.util.Encodable; import com.fr.third.org.bouncycastle.util.Encodable;
@ -11,20 +12,26 @@ import com.fr.third.org.bouncycastle.util.Encodable;
public abstract class ASN1Object public abstract class ASN1Object
implements ASN1Encodable, Encodable implements ASN1Encodable, Encodable
{ {
public void encodeTo(OutputStream output) throws IOException
{
ASN1OutputStream.create(output).writeObject(this);
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
ASN1OutputStream.create(output, encoding).writeObject(this);
}
/** /**
* Return the default BER or DER encoding for this object. * Return the default BER or DER encoding for this object.
* *
* @return BER/DER byte encoded object. * @return BER/DER byte encoded object.
* @throws java.io.IOException on encoding error. * @throws java.io.IOException on encoding error.
*/ */
public byte[] getEncoded() public byte[] getEncoded() throws IOException
throws IOException
{ {
ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ASN1OutputStream aOut = new ASN1OutputStream(bOut); encodeTo(bOut);
aOut.writeObject(this);
return bOut.toByteArray(); return bOut.toByteArray();
} }
@ -35,31 +42,12 @@ public abstract class ASN1Object
* @return byte encoded object. * @return byte encoded object.
* @throws IOException on encoding error. * @throws IOException on encoding error.
*/ */
public byte[] getEncoded( public byte[] getEncoded(String encoding) throws IOException
String encoding)
throws IOException
{
if (encoding.equals(ASN1Encoding.DER))
{ {
ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut); encodeTo(bOut, encoding);
dOut.writeObject(this);
return bOut.toByteArray(); return bOut.toByteArray();
} }
else if (encoding.equals(ASN1Encoding.DL))
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DLOutputStream dOut = new DLOutputStream(bOut);
dOut.writeObject(this);
return bOut.toByteArray();
}
return this.getEncoded();
}
public int hashCode() public int hashCode()
{ {

48
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1ObjectIdentifier.java

@ -33,9 +33,14 @@ public class ASN1ObjectIdentifier
return (ASN1ObjectIdentifier)obj; return (ASN1ObjectIdentifier)obj;
} }
if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier) if (obj instanceof ASN1Encodable)
{ {
return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive(); ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
if (primitive instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)primitive;
}
} }
if (obj instanceof byte[]) if (obj instanceof byte[])
@ -169,7 +174,7 @@ public class ASN1ObjectIdentifier
{ {
if (identifier == null) if (identifier == null)
{ {
throw new IllegalArgumentException("'identifier' cannot be null"); throw new NullPointerException("'identifier' cannot be null");
} }
if (!isValidIdentifier(identifier)) if (!isValidIdentifier(identifier))
{ {
@ -322,15 +327,9 @@ public class ASN1ObjectIdentifier
return 1 + StreamUtil.calculateBodyLength(length) + length; return 1 + StreamUtil.calculateBodyLength(length) + length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
byte[] enc = getBody(); out.writeEncoded(withTag, BERTags.OBJECT_IDENTIFIER, getBody());
out.write(BERTags.OBJECT_IDENTIFIER);
out.writeLength(enc.length);
out.write(enc);
} }
public int hashCode() public int hashCode()
@ -362,35 +361,40 @@ public class ASN1ObjectIdentifier
private static boolean isValidBranchID( private static boolean isValidBranchID(
String branchID, int start) String branchID, int start)
{ {
boolean periodAllowed = false; int digitCount = 0;
int pos = branchID.length(); int pos = branchID.length();
while (--pos >= start) while (--pos >= start)
{ {
char ch = branchID.charAt(pos); char ch = branchID.charAt(pos);
// TODO Leading zeroes? if (ch == '.')
if ('0' <= ch && ch <= '9')
{ {
periodAllowed = true; if (0 == digitCount
continue; || (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
{
return false;
} }
if (ch == '.') digitCount = 0;
}
else if ('0' <= ch && ch <= '9')
{ {
if (!periodAllowed) ++digitCount;
}
else
{ {
return false; return false;
} }
periodAllowed = false;
continue;
} }
if (0 == digitCount
|| (digitCount > 1 && branchID.charAt(pos + 1) == '0'))
{
return false; return false;
} }
return periodAllowed; return true;
} }
private static boolean isValidIdentifier( private static boolean isValidIdentifier(

69
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1OctetString.java

@ -105,26 +105,76 @@ public abstract class ASN1OctetString
/** /**
* return an Octet String from a tagged object. * return an Octet String from a tagged object.
* *
* @param obj the tagged object holding the object we want. * @param taggedObject the tagged object holding the object we want.
* @param explicit true if the object is meant to be explicitly * @param explicit true if the object is meant to be explicitly
* tagged false otherwise. * tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
*/ */
public static ASN1OctetString getInstance( public static ASN1OctetString getInstance(
ASN1TaggedObject obj, ASN1TaggedObject taggedObject,
boolean explicit) boolean explicit)
{ {
ASN1Primitive o = obj.getObject(); if (explicit)
{
if (!taggedObject.isExplicit())
{
throw new IllegalArgumentException("object implicit - explicit expected.");
}
if (explicit || o instanceof ASN1OctetString) return getInstance(taggedObject.getObject());
}
ASN1Primitive o = taggedObject.getObject();
/*
* constructed object which appears to be explicitly tagged and it's really implicit means
* we have to add the surrounding octet string.
*/
if (taggedObject.isExplicit())
{ {
return getInstance(o); ASN1OctetString singleSegment = ASN1OctetString.getInstance(o);
if (taggedObject instanceof BERTaggedObject)
{
return new BEROctetString(new ASN1OctetString[]{ singleSegment });
}
// TODO Should really be similar to the BERTaggedObject case above:
// return new DLOctetString(new ASN1OctetString[]{ singleSegment });
return (ASN1OctetString)new BEROctetString(new ASN1OctetString[]{ singleSegment }).toDLObject();
} }
else
if (o instanceof ASN1OctetString)
{ {
return BEROctetString.fromSequence(ASN1Sequence.getInstance(o)); ASN1OctetString s = (ASN1OctetString)o;
if (taggedObject instanceof BERTaggedObject)
{
return s;
}
return (ASN1OctetString)s.toDLObject();
}
/*
* in this case the parser returns a sequence, convert it into an octet string.
*/
if (o instanceof ASN1Sequence)
{
ASN1Sequence s = (ASN1Sequence)o;
if (taggedObject instanceof BERTaggedObject)
{
return BEROctetString.fromSequence(s);
} }
// TODO Should really be similar to the BERTaggedObject case above:
// return DLOctetString.fromSequence(s);
return (ASN1OctetString)BEROctetString.fromSequence(s).toDLObject();
}
throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
} }
/** /**
@ -174,7 +224,7 @@ public abstract class ASN1OctetString
{ {
if (string == null) if (string == null)
{ {
throw new NullPointerException("string cannot be null"); throw new NullPointerException("'string' cannot be null");
} }
this.string = string; this.string = string;
} }
@ -242,8 +292,7 @@ public abstract class ASN1OctetString
return new DEROctetString(string); return new DEROctetString(string);
} }
abstract void encode(ASN1OutputStream out) abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
throws IOException;
public String toString() public String toString()
{ {

263
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1OutputStream.java

@ -2,21 +2,45 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Enumeration;
/** /**
* Stream that produces output based on the default encoding for the passed in objects. * Stream that produces output based on the default encoding for the passed in objects.
*/ */
public class ASN1OutputStream public class ASN1OutputStream
{ {
public static ASN1OutputStream create(OutputStream out)
{
return new ASN1OutputStream(out);
}
public static ASN1OutputStream create(OutputStream out, String encoding)
{
if (encoding.equals(ASN1Encoding.DER))
{
return new DEROutputStream(out);
}
else if (encoding.equals(ASN1Encoding.DL))
{
return new DLOutputStream(out);
}
else
{
return new ASN1OutputStream(out);
}
}
private OutputStream os; private OutputStream os;
public ASN1OutputStream( /**
OutputStream os) * @deprecated Use {@link ASN1OutputStream#create(OutputStream)} instead.
*/
public ASN1OutputStream(OutputStream os)
{ {
this.os = os; this.os = os;
} }
void writeLength( final void writeLength(
int length) int length)
throws IOException throws IOException
{ {
@ -43,37 +67,173 @@ public class ASN1OutputStream
} }
} }
void write(int b) final void write(int b)
throws IOException throws IOException
{ {
os.write(b); os.write(b);
} }
void write(byte[] bytes) final void write(byte[] bytes, int off, int len)
throws IOException throws IOException
{ {
os.write(bytes); os.write(bytes, off, len);
} }
void write(byte[] bytes, int off, int len) final void writeElements(ASN1Encodable[] elements)
throws IOException throws IOException
{ {
os.write(bytes, off, len); int count = elements.length;
for (int i = 0; i < count; ++i)
{
ASN1Primitive primitive = elements[i].toASN1Primitive();
writePrimitive(primitive, true);
}
}
final void writeElements(Enumeration elements)
throws IOException
{
while (elements.hasMoreElements())
{
ASN1Primitive primitive = ((ASN1Encodable)elements.nextElement()).toASN1Primitive();
writePrimitive(primitive, true);
}
}
final void writeEncoded(
boolean withTag,
int tag,
byte contents)
throws IOException
{
if (withTag)
{
write(tag);
}
writeLength(1);
write(contents);
}
final void writeEncoded(
boolean withTag,
int tag,
byte[] contents)
throws IOException
{
if (withTag)
{
write(tag);
}
writeLength(contents.length);
write(contents, 0, contents.length);
} }
void writeEncoded( final void writeEncoded(
boolean withTag,
int tag, int tag,
byte[] bytes) byte[] contents,
int contentsOff,
int contentsLen)
throws IOException
{
if (withTag)
{
write(tag);
}
writeLength(contentsLen);
write(contents, contentsOff, contentsLen);
}
final void writeEncoded(
boolean withTag,
int tag,
byte headByte,
byte[] tailBytes)
throws IOException
{
if (withTag)
{
write(tag);
}
writeLength(1 + tailBytes.length);
write(headByte);
write(tailBytes, 0, tailBytes.length);
}
final void writeEncoded(
boolean withTag,
int tag,
byte headByte,
byte[] body,
int bodyOff,
int bodyLen,
byte tailByte)
throws IOException
{
if (withTag)
{
write(tag);
}
writeLength(2 + bodyLen);
write(headByte);
write(body, bodyOff, bodyLen);
write(tailByte);
}
final void writeEncoded(boolean withTag, int flags, int tagNo, byte[] contents)
throws IOException
{
writeTag(withTag, flags, tagNo);
writeLength(contents.length);
write(contents, 0, contents.length);
}
final void writeEncodedIndef(boolean withTag, int flags, int tagNo, byte[] contents)
throws IOException throws IOException
{
writeTag(withTag, flags, tagNo);
write(0x80);
write(contents, 0, contents.length);
write(0x00);
write(0x00);
}
final void writeEncodedIndef(boolean withTag, int tag, ASN1Encodable[] elements)
throws IOException
{
if (withTag)
{ {
write(tag); write(tag);
writeLength(bytes.length); }
write(bytes); write(0x80);
writeElements(elements);
write(0x00);
write(0x00);
} }
void writeTag(int flags, int tagNo) final void writeEncodedIndef(boolean withTag, int tag, Enumeration elements)
throws IOException throws IOException
{ {
if (withTag)
{
write(tag);
}
write(0x80);
writeElements(elements);
write(0x00);
write(0x00);
}
final void writeTag(boolean withTag, int flags, int tagNo)
throws IOException
{
if (!withTag)
{
return;
}
if (tagNo < 31) if (tagNo < 31)
{ {
write(flags | tagNo); write(flags | tagNo);
@ -104,46 +264,41 @@ public class ASN1OutputStream
} }
} }
void writeEncoded(int flags, int tagNo, byte[] bytes) /**
throws IOException * @deprecated Will be removed.
{ */
writeTag(flags, tagNo);
writeLength(bytes.length);
write(bytes);
}
protected void writeNull() protected void writeNull()
throws IOException throws IOException
{ {
os.write(BERTags.NULL); write(BERTags.NULL);
os.write(0x00); write(0x00);
} }
public void writeObject( public void writeObject(ASN1Encodable obj) throws IOException
ASN1Encodable obj)
throws IOException
{ {
if (obj != null) if (null == obj)
{
obj.toASN1Primitive().encode(this);
}
else
{ {
throw new IOException("null object detected"); throw new IOException("null object detected");
} }
writePrimitive(obj.toASN1Primitive(), true);
flushInternal();
} }
void writeImplicitObject(ASN1Primitive obj) public void writeObject(ASN1Primitive primitive) throws IOException
throws IOException
{
if (obj != null)
{ {
obj.encode(new ImplicitOutputStream(os)); if (null == primitive)
}
else
{ {
throw new IOException("null object detected"); throw new IOException("null object detected");
} }
writePrimitive(primitive, true);
flushInternal();
}
void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
{
primitive.encode(this, withTag);
} }
public void close() public void close()
@ -158,37 +313,19 @@ public class ASN1OutputStream
os.flush(); os.flush();
} }
ASN1OutputStream getDERSubStream() void flushInternal()
{ throws IOException
return new DEROutputStream(os);
}
ASN1OutputStream getDLSubStream()
{ {
return new DLOutputStream(os); // Placeholder to support future internal buffering
} }
private class ImplicitOutputStream DEROutputStream getDERSubStream()
extends ASN1OutputStream
{
private boolean first = true;
public ImplicitOutputStream(OutputStream os)
{ {
super(os); return new DEROutputStream(os);
} }
public void write(int b) ASN1OutputStream getDLSubStream()
throws IOException
{
if (first)
{
first = false;
}
else
{ {
super.write(b); return new DLOutputStream(os);
}
}
} }
} }

24
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Primitive.java

@ -1,6 +1,7 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
/** /**
* Base class for ASN.1 primitive objects. These are the actual objects used to generate byte encodings. * Base class for ASN.1 primitive objects. These are the actual objects used to generate byte encodings.
@ -10,7 +11,16 @@ public abstract class ASN1Primitive
{ {
ASN1Primitive() ASN1Primitive()
{ {
}
public void encodeTo(OutputStream output) throws IOException
{
ASN1OutputStream.create(output).writeObject(this);
}
public void encodeTo(OutputStream output, String encoding) throws IOException
{
ASN1OutputStream.create(output, encoding).writeObject(this);
} }
/** /**
@ -52,7 +62,17 @@ public abstract class ASN1Primitive
return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive()); return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive());
} }
public ASN1Primitive toASN1Primitive() public final boolean equals(ASN1Encodable other)
{
return this == other || (null != other && asn1Equals(other.toASN1Primitive()));
}
public final boolean equals(ASN1Primitive other)
{
return this == other || asn1Equals(other);
}
public final ASN1Primitive toASN1Primitive()
{ {
return this; return this;
} }
@ -92,7 +112,7 @@ public abstract class ASN1Primitive
*/ */
abstract int encodedLength() throws IOException; abstract int encodedLength() throws IOException;
abstract void encode(ASN1OutputStream out) throws IOException; abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
/** /**
* Equality (similarity) comparison for two ASN1Primitive objects. * Equality (similarity) comparison for two ASN1Primitive objects.

222
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Sequence.java

@ -3,7 +3,7 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.NoSuchElementException;
import com.fr.third.org.bouncycastle.util.Arrays; import com.fr.third.org.bouncycastle.util.Arrays;
@ -60,7 +60,8 @@ public abstract class ASN1Sequence
extends ASN1Primitive extends ASN1Primitive
implements com.fr.third.org.bouncycastle.util.Iterable<ASN1Encodable> implements com.fr.third.org.bouncycastle.util.Iterable<ASN1Encodable>
{ {
protected Vector seq = new Vector(); // NOTE: Only non-final to support LazyEncodedSequence
ASN1Encodable[] elements;
/** /**
* Return an ASN1Sequence from the given object. * Return an ASN1Sequence from the given object.
@ -114,7 +115,7 @@ public abstract class ASN1Sequence
* dealing with implicitly tagged sequences you really <b>should</b> * dealing with implicitly tagged sequences you really <b>should</b>
* be using this method. * be using this method.
* *
* @param obj the tagged object. * @param taggedObject the tagged object.
* @param explicit true if the object is meant to be explicitly tagged, * @param explicit true if the object is meant to be explicitly tagged,
* false otherwise. * false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
@ -122,48 +123,48 @@ public abstract class ASN1Sequence
* @return an ASN1Sequence instance. * @return an ASN1Sequence instance.
*/ */
public static ASN1Sequence getInstance( public static ASN1Sequence getInstance(
ASN1TaggedObject obj, ASN1TaggedObject taggedObject,
boolean explicit) boolean explicit)
{ {
if (explicit) if (explicit)
{ {
if (!obj.isExplicit()) if (!taggedObject.isExplicit())
{ {
throw new IllegalArgumentException("object implicit - explicit expected."); throw new IllegalArgumentException("object implicit - explicit expected.");
} }
return ASN1Sequence.getInstance(obj.getObject().toASN1Primitive()); return getInstance(taggedObject.getObject());
} }
else
{
ASN1Primitive o = obj.getObject();
// ASN1Primitive o = taggedObject.getObject();
// constructed object which appears to be explicitly tagged
// when it should be implicit means we have to add the /*
// surrounding sequence. * constructed object which appears to be explicitly tagged when it should be implicit means
// * we have to add the surrounding sequence.
if (obj.isExplicit()) */
if (taggedObject.isExplicit())
{ {
if (obj instanceof BERTaggedObject) if (taggedObject instanceof BERTaggedObject)
{ {
return new BERSequence(o); return new BERSequence(o);
} }
else
{
return new DLSequence(o); return new DLSequence(o);
} }
}
else
{
if (o instanceof ASN1Sequence) if (o instanceof ASN1Sequence)
{ {
return (ASN1Sequence)o; ASN1Sequence s = (ASN1Sequence)o;
}
if (taggedObject instanceof BERTaggedObject)
{
return s;
} }
return (ASN1Sequence)s.toDLObject();
} }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
} }
/** /**
@ -171,79 +172,105 @@ public abstract class ASN1Sequence
*/ */
protected ASN1Sequence() protected ASN1Sequence()
{ {
this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
} }
/** /**
* Create a SEQUENCE containing one object. * Create a SEQUENCE containing one object.
* @param obj the object to be put in the SEQUENCE. * @param obj the object to be put in the SEQUENCE.
*/ */
protected ASN1Sequence( protected ASN1Sequence(ASN1Encodable element)
ASN1Encodable obj) {
if (null == element)
{ {
seq.addElement(obj); throw new NullPointerException("'element' cannot be null");
}
this.elements = new ASN1Encodable[]{ element };
} }
/** /**
* Create a SEQUENCE containing a vector of objects. * Create a SEQUENCE containing a vector of objects.
* @param v the vector of objects to be put in the SEQUENCE. * @param elementVector the vector of objects to be put in the SEQUENCE.
*/ */
protected ASN1Sequence( protected ASN1Sequence(ASN1EncodableVector elementVector)
ASN1EncodableVector v)
{ {
for (int i = 0; i != v.size(); i++) if (null == elementVector)
{ {
seq.addElement(v.get(i)); throw new NullPointerException("'elementVector' cannot be null");
} }
this.elements = elementVector.takeElements();
} }
/** /**
* Create a SEQUENCE containing an array of objects. * Create a SEQUENCE containing an array of objects.
* @param array the array of objects to be put in the SEQUENCE. * @param array the array of objects to be put in the SEQUENCE.
*/ */
protected ASN1Sequence( protected ASN1Sequence(ASN1Encodable[] elements)
ASN1Encodable[] array)
{ {
for (int i = 0; i != array.length; i++) if (Arrays.isNullOrContainsNull(elements))
{ {
seq.addElement(array[i]); throw new NullPointerException("'elements' cannot be null, or contain null");
} }
this.elements = ASN1EncodableVector.cloneElements(elements);
} }
public ASN1Encodable[] toArray() ASN1Sequence(ASN1Encodable[] elements, boolean clone)
{ {
ASN1Encodable[] values = new ASN1Encodable[this.size()]; this.elements = clone ? ASN1EncodableVector.cloneElements(elements) : elements;
}
for (int i = 0; i != this.size(); i++) public ASN1Encodable[] toArray()
{ {
values[i] = this.getObjectAt(i); return ASN1EncodableVector.cloneElements(elements);
} }
return values; ASN1Encodable[] toArrayInternal()
{
return elements;
} }
public Enumeration getObjects() public Enumeration getObjects()
{ {
return seq.elements(); return new Enumeration()
{
private int pos = 0;
public boolean hasMoreElements()
{
return pos < elements.length;
}
public Object nextElement()
{
if (pos >= elements.length)
{
throw new NoSuchElementException("ASN1Sequence Enumeration");
}
return elements[pos++];
}
};
} }
public ASN1SequenceParser parser() public ASN1SequenceParser parser()
{ {
final ASN1Sequence outer = this; // NOTE: Call size() here to 'force' a LazyEncodedSequence
final int count = size();
return new ASN1SequenceParser() return new ASN1SequenceParser()
{ {
private final int max = size(); private int pos = 0;
private int index;
public ASN1Encodable readObject() throws IOException public ASN1Encodable readObject() throws IOException
{ {
if (index == max) if (count == pos)
{ {
return null; return null;
} }
ASN1Encodable obj = getObjectAt(index++); ASN1Encodable obj = elements[pos++];
if (obj instanceof ASN1Sequence) if (obj instanceof ASN1Sequence)
{ {
return ((ASN1Sequence)obj).parser(); return ((ASN1Sequence)obj).parser();
@ -258,12 +285,12 @@ public abstract class ASN1Sequence
public ASN1Primitive getLoadedObject() public ASN1Primitive getLoadedObject()
{ {
return outer; return ASN1Sequence.this;
} }
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
return outer; return ASN1Sequence.this;
} }
}; };
} }
@ -274,10 +301,9 @@ public abstract class ASN1Sequence
* @param index the sequence number (starting at zero) of the object * @param index the sequence number (starting at zero) of the object
* @return the object at the sequence position indicated by index. * @return the object at the sequence position indicated by index.
*/ */
public ASN1Encodable getObjectAt( public ASN1Encodable getObjectAt(int index)
int index)
{ {
return (ASN1Encodable)seq.elementAt(index); return elements[index];
} }
/** /**
@ -287,67 +313,51 @@ public abstract class ASN1Sequence
*/ */
public int size() public int size()
{ {
return seq.size(); return elements.length;
} }
public int hashCode() public int hashCode()
{ {
Enumeration e = this.getObjects(); // return Arrays.hashCode(elements);
int hashCode = size(); int i = elements.length;
int hc = i + 1;
while (e.hasMoreElements()) while (--i >= 0)
{ {
Object o = getNext(e); hc *= 257;
hashCode *= 17; hc ^= elements[i].toASN1Primitive().hashCode();
hashCode ^= o.hashCode();
} }
return hashCode; return hc;
} }
boolean asn1Equals( boolean asn1Equals(ASN1Primitive other)
ASN1Primitive o)
{ {
if (!(o instanceof ASN1Sequence)) if (!(other instanceof ASN1Sequence))
{ {
return false; return false;
} }
ASN1Sequence other = (ASN1Sequence)o; ASN1Sequence that = (ASN1Sequence)other;
if (this.size() != other.size()) int count = this.size();
if (that.size() != count)
{ {
return false; return false;
} }
Enumeration s1 = this.getObjects(); for (int i = 0; i < count; ++i)
Enumeration s2 = other.getObjects();
while (s1.hasMoreElements())
{ {
ASN1Encodable obj1 = getNext(s1); ASN1Primitive p1 = this.elements[i].toASN1Primitive();
ASN1Encodable obj2 = getNext(s2); ASN1Primitive p2 = that.elements[i].toASN1Primitive();
ASN1Primitive o1 = obj1.toASN1Primitive();
ASN1Primitive o2 = obj2.toASN1Primitive();
if (o1 == o2 || o1.equals(o2)) if (p1 != p2 && !p1.asn1Equals(p2))
{ {
continue;
}
return false; return false;
} }
return true;
} }
private ASN1Encodable getNext(Enumeration e) return true;
{
ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
return encObj;
} }
/** /**
@ -356,11 +366,7 @@ public abstract class ASN1Sequence
*/ */
ASN1Primitive toDERObject() ASN1Primitive toDERObject()
{ {
ASN1Sequence derSeq = new DERSequence(); return new DERSequence(elements, false);
derSeq.seq = this.seq;
return derSeq;
} }
/** /**
@ -369,11 +375,7 @@ public abstract class ASN1Sequence
*/ */
ASN1Primitive toDLObject() ASN1Primitive toDLObject()
{ {
ASN1Sequence dlSeq = new DLSequence(); return new DLSequence(elements, false);
dlSeq.seq = this.seq;
return dlSeq;
} }
boolean isConstructed() boolean isConstructed()
@ -381,16 +383,34 @@ public abstract class ASN1Sequence
return true; return true;
} }
abstract void encode(ASN1OutputStream out) abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
throws IOException;
public String toString() public String toString()
{ {
return seq.toString(); // NOTE: Call size() here to 'force' a LazyEncodedSequence
int count = size();
if (0 == count)
{
return "[]";
}
StringBuffer sb = new StringBuffer();
sb.append('[');
for (int i = 0;;)
{
sb.append(elements[i]);
if (++i >= count)
{
break;
}
sb.append(", ");
}
sb.append(']');
return sb.toString();
} }
public Iterator<ASN1Encodable> iterator() public Iterator<ASN1Encodable> iterator()
{ {
return new Arrays.Iterator<ASN1Encodable>(toArray()); return new Arrays.Iterator<ASN1Encodable>(elements);
} }
} }

414
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1Set.java

@ -3,7 +3,7 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.NoSuchElementException;
import com.fr.third.org.bouncycastle.util.Arrays; import com.fr.third.org.bouncycastle.util.Arrays;
@ -98,8 +98,8 @@ public abstract class ASN1Set
extends ASN1Primitive extends ASN1Primitive
implements com.fr.third.org.bouncycastle.util.Iterable<ASN1Encodable> implements com.fr.third.org.bouncycastle.util.Iterable<ASN1Encodable>
{ {
private Vector set = new Vector(); protected final ASN1Encodable[] elements;
private boolean isSorted = false; protected final boolean isSorted;
/** /**
* return an ASN1Set from the given object. * return an ASN1Set from the given object.
@ -153,7 +153,7 @@ public abstract class ASN1Set
* dealing with implicitly tagged sets you really <b>should</b> * dealing with implicitly tagged sets you really <b>should</b>
* be using this method. * be using this method.
* *
* @param obj the tagged object. * @param taggedObject the tagged object.
* @param explicit true if the object is meant to be explicitly tagged * @param explicit true if the object is meant to be explicitly tagged
* false otherwise. * false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
@ -161,125 +161,164 @@ public abstract class ASN1Set
* @return an ASN1Set instance. * @return an ASN1Set instance.
*/ */
public static ASN1Set getInstance( public static ASN1Set getInstance(
ASN1TaggedObject obj, ASN1TaggedObject taggedObject,
boolean explicit) boolean explicit)
{ {
if (explicit) if (explicit)
{ {
if (!obj.isExplicit()) if (!taggedObject.isExplicit())
{ {
throw new IllegalArgumentException("object implicit - explicit expected."); throw new IllegalArgumentException("object implicit - explicit expected.");
} }
return (ASN1Set)obj.getObject(); return getInstance(taggedObject.getObject());
} }
else
{
ASN1Primitive o = obj.getObject();
// ASN1Primitive o = taggedObject.getObject();
// constructed object which appears to be explicitly tagged
// and it's really implicit means we have to add the /*
// surrounding set. * constructed object which appears to be explicitly tagged and it's really implicit means
// * we have to add the surrounding set.
if (obj.isExplicit()) */
if (taggedObject.isExplicit())
{ {
if (obj instanceof BERTaggedObject) if (taggedObject instanceof BERTaggedObject)
{ {
return new BERSet(o); return new BERSet(o);
} }
else
{
return new DLSet(o); return new DLSet(o);
} }
}
else
{
if (o instanceof ASN1Set) if (o instanceof ASN1Set)
{ {
return (ASN1Set)o; ASN1Set s = (ASN1Set)o;
if (taggedObject instanceof BERTaggedObject)
{
return s;
}
return (ASN1Set)s.toDLObject();
} }
// /*
// in this case the parser returns a sequence, convert it * in this case the parser returns a sequence, convert it into a set.
// into a set. */
//
if (o instanceof ASN1Sequence) if (o instanceof ASN1Sequence)
{ {
ASN1Sequence s = (ASN1Sequence)o; ASN1Sequence s = (ASN1Sequence)o;
if (obj instanceof BERTaggedObject) // NOTE: Will force() a LazyEncodedSequence
{ ASN1Encodable[] elements = s.toArrayInternal();
return new BERSet(s.toArray());
} if (taggedObject instanceof BERTaggedObject)
else
{ {
return new DLSet(s.toArray()); return new BERSet(false, elements);
}
}
} }
return new DLSet(false, elements);
} }
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); throw new IllegalArgumentException("unknown object in getInstance: " + taggedObject.getClass().getName());
} }
protected ASN1Set() protected ASN1Set()
{ {
this.elements = ASN1EncodableVector.EMPTY_ELEMENTS;
this.isSorted = true;
} }
/** /**
* Create a SET containing one object * Create a SET containing one object
* @param obj object to be added to the SET. * @param element object to be added to the SET.
*/ */
protected ASN1Set( protected ASN1Set(ASN1Encodable element)
ASN1Encodable obj)
{ {
set.addElement(obj); if (null == element)
{
throw new NullPointerException("'element' cannot be null");
}
this.elements = new ASN1Encodable[]{ element };
this.isSorted = true;
} }
/** /**
* Create a SET containing a vector of objects. * Create a SET containing a vector of objects.
* @param v a vector of objects to make up the SET. * @param elementVector a vector of objects to make up the SET.
* @param doSort true if should be sorted DER style, false otherwise. * @param doSort true if should be sorted DER style, false otherwise.
*/ */
protected ASN1Set( protected ASN1Set(ASN1EncodableVector elementVector, boolean doSort)
ASN1EncodableVector v,
boolean doSort)
{ {
for (int i = 0; i != v.size(); i++) if (null == elementVector)
{ {
set.addElement(v.get(i)); throw new NullPointerException("'elementVector' cannot be null");
} }
if (doSort) ASN1Encodable[] tmp;
if (doSort && elementVector.size() >= 2)
{ {
this.sort(); tmp = elementVector.copyElements();
sort(tmp);
} }
else
{
tmp = elementVector.takeElements();
}
this.elements = tmp;
this.isSorted = doSort || tmp.length < 2;
} }
/** /**
* Create a SET containing an array of objects. * Create a SET containing an array of objects.
* @param array an array of objects to make up the SET. * @param elements an array of objects to make up the SET.
* @param doSort true if should be sorted DER style, false otherwise. * @param doSort true if should be sorted DER style, false otherwise.
*/ */
protected ASN1Set( protected ASN1Set(ASN1Encodable[] elements, boolean doSort)
ASN1Encodable[] array,
boolean doSort)
{ {
for (int i = 0; i != array.length; i++) if (Arrays.isNullOrContainsNull(elements))
{ {
set.addElement(array[i]); throw new NullPointerException("'elements' cannot be null, or contain null");
} }
if (doSort) ASN1Encodable[] tmp = ASN1EncodableVector.cloneElements(elements);
if (doSort && tmp.length >= 2)
{ {
this.sort(); sort(tmp);
} }
this.elements = tmp;
this.isSorted = doSort || tmp.length < 2;
}
ASN1Set(boolean isSorted, ASN1Encodable[] elements)
{
this.elements = elements;
this.isSorted = isSorted || elements.length < 2;
} }
public Enumeration getObjects() public Enumeration getObjects()
{ {
return set.elements(); return new Enumeration()
{
private int pos = 0;
public boolean hasMoreElements()
{
return pos < elements.length;
}
public Object nextElement()
{
if (pos >= elements.length)
{
throw new NoSuchElementException("ASN1Set Enumeration");
}
return elements[pos++];
}
};
} }
/** /**
@ -288,10 +327,9 @@ public abstract class ASN1Set
* @param index the set number (starting at zero) of the object * @param index the set number (starting at zero) of the object
* @return the object at the set position indicated by index. * @return the object at the set position indicated by index.
*/ */
public ASN1Encodable getObjectAt( public ASN1Encodable getObjectAt(int index)
int index)
{ {
return (ASN1Encodable)set.elementAt(index); return elements[index];
} }
/** /**
@ -301,39 +339,30 @@ public abstract class ASN1Set
*/ */
public int size() public int size()
{ {
return set.size(); return elements.length;
} }
public ASN1Encodable[] toArray() public ASN1Encodable[] toArray()
{ {
ASN1Encodable[] values = new ASN1Encodable[this.size()]; return ASN1EncodableVector.cloneElements(elements);
for (int i = 0; i != this.size(); i++)
{
values[i] = this.getObjectAt(i);
}
return values;
} }
public ASN1SetParser parser() public ASN1SetParser parser()
{ {
final ASN1Set outer = this; final int count = size();
return new ASN1SetParser() return new ASN1SetParser()
{ {
private final int max = size(); private int pos = 0;
private int index;
public ASN1Encodable readObject() throws IOException public ASN1Encodable readObject() throws IOException
{ {
if (index == max) if (count == pos)
{ {
return null; return null;
} }
ASN1Encodable obj = getObjectAt(index++); ASN1Encodable obj = elements[pos++];
if (obj instanceof ASN1Sequence) if (obj instanceof ASN1Sequence)
{ {
return ((ASN1Sequence)obj).parser(); return ((ASN1Sequence)obj).parser();
@ -348,30 +377,29 @@ public abstract class ASN1Set
public ASN1Primitive getLoadedObject() public ASN1Primitive getLoadedObject()
{ {
return outer; return ASN1Set.this;
} }
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
return outer; return ASN1Set.this;
} }
}; };
} }
public int hashCode() public int hashCode()
{ {
Enumeration e = this.getObjects(); // return Arrays.hashCode(elements);
int hashCode = size(); int i = elements.length;
int hc = i + 1;
while (e.hasMoreElements()) // NOTE: Order-independent contribution of elements to avoid sorting
while (--i >= 0)
{ {
Object o = getNext(e); hc += elements[i].toASN1Primitive().hashCode();
hashCode *= 17;
hashCode ^= o.hashCode();
} }
return hashCode; return hc;
} }
/** /**
@ -380,31 +408,18 @@ public abstract class ASN1Set
*/ */
ASN1Primitive toDERObject() ASN1Primitive toDERObject()
{ {
ASN1Encodable[] tmp;
if (isSorted) if (isSorted)
{ {
ASN1Set derSet = new DERSet(); tmp = elements;
derSet.set = this.set;
return derSet;
} }
else else
{ {
Vector v = new Vector(); tmp = (ASN1Encodable[])elements.clone();
sort(tmp);
for (int i = 0; i != set.size(); i++)
{
v.addElement(set.elementAt(i));
} }
ASN1Set derSet = new DERSet(); return new DERSet(true, tmp);
derSet.set = v;
derSet.sort();
return derSet;
}
} }
/** /**
@ -413,83 +428,77 @@ public abstract class ASN1Set
*/ */
ASN1Primitive toDLObject() ASN1Primitive toDLObject()
{ {
ASN1Set derSet = new DLSet(); return new DLSet(isSorted, elements);
derSet.set = this.set;
return derSet;
} }
boolean asn1Equals( boolean asn1Equals(ASN1Primitive other)
ASN1Primitive o)
{ {
if (!(o instanceof ASN1Set)) if (!(other instanceof ASN1Set))
{ {
return false; return false;
} }
ASN1Set other = (ASN1Set)o; ASN1Set that = (ASN1Set)other;
if (this.size() != other.size()) int count = this.size();
if (that.size() != count)
{ {
return false; return false;
} }
Enumeration s1 = this.getObjects(); DERSet dis = (DERSet)this.toDERObject();
Enumeration s2 = other.getObjects(); DERSet dat = (DERSet)that.toDERObject();
while (s1.hasMoreElements()) for (int i = 0; i < count; ++i)
{ {
ASN1Encodable obj1 = getNext(s1); ASN1Primitive p1 = dis.elements[i].toASN1Primitive();
ASN1Encodable obj2 = getNext(s2); ASN1Primitive p2 = dat.elements[i].toASN1Primitive();
ASN1Primitive o1 = obj1.toASN1Primitive(); if (p1 != p2 && !p1.asn1Equals(p2))
ASN1Primitive o2 = obj2.toASN1Primitive();
if (o1 == o2 || o1.equals(o2))
{ {
continue;
}
return false; return false;
} }
}
return true; return true;
} }
private ASN1Encodable getNext(Enumeration e) boolean isConstructed()
{
ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
// unfortunately null was allowed as a substitute for DER null
if (encObj == null)
{ {
return DERNull.INSTANCE; return true;
} }
return encObj; abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
}
/** public String toString()
* return true if a <= b (arrays are assumed padded with zeros).
*/
private boolean lessThanOrEqual(
byte[] a,
byte[] b)
{ {
int len = Math.min(a.length, b.length); int count = size();
for (int i = 0; i != len; ++i) if (0 == count)
{ {
if (a[i] != b[i]) return "[]";
}
StringBuffer sb = new StringBuffer();
sb.append('[');
for (int i = 0;;)
{
sb.append(elements[i]);
if (++i >= count)
{ {
return (a[i] & 0xff) < (b[i] & 0xff); break;
} }
sb.append(", ");
} }
return len == a.length; sb.append(']');
return sb.toString();
}
public Iterator<ASN1Encodable> iterator()
{
return new Arrays.Iterator<ASN1Encodable>(toArray());
} }
private byte[] getDEREncoded( private static byte[] getDEREncoded(ASN1Encodable obj)
ASN1Encodable obj)
{ {
try try
{ {
@ -501,67 +510,98 @@ public abstract class ASN1Set
} }
} }
protected void sort() /**
{ * return true if a <= b (arrays are assumed padded with zeros).
if (!isSorted) */
{ private static boolean lessThanOrEqual(byte[] a, byte[] b)
isSorted = true;
if (set.size() > 1)
{ {
boolean swapped = true; // assert a.length >= 2 && b.length >= 2;
int lastSwap = set.size() - 1;
while (swapped) /*
* NOTE: Set elements in DER encodings are ordered first according to their tags (class and
* number); the CONSTRUCTED bit is not part of the tag.
*
* For SET-OF, this is unimportant. All elements have the same tag and DER requires them to
* either all be in constructed form or all in primitive form, according to that tag. The
* elements are effectively ordered according to their content octets.
*
* For SET, the elements will have distinct tags, and each will be in constructed or
* primitive form accordingly. Failing to ignore the CONSTRUCTED bit could therefore lead to
* ordering inversions.
*/
int a0 = a[0] & ~BERTags.CONSTRUCTED;
int b0 = b[0] & ~BERTags.CONSTRUCTED;
if (a0 != b0)
{ {
int index = 0; return a0 < b0;
int swapIndex = 0; }
byte[] a = getDEREncoded((ASN1Encodable)set.elementAt(0));
swapped = false;
while (index != lastSwap) int last = Math.min(a.length, b.length) - 1;
for (int i = 1; i < last; ++i)
{ {
byte[] b = getDEREncoded((ASN1Encodable)set.elementAt(index + 1)); if (a[i] != b[i])
if (lessThanOrEqual(a, b))
{ {
a = b; return (a[i] & 0xFF) < (b[i] & 0xFF);
} }
else }
return (a[last] & 0xFF) <= (b[last] & 0xFF);
}
private static void sort(ASN1Encodable[] t)
{ {
Object o = set.elementAt(index); int count = t.length;
if (count < 2)
{
return;
}
set.setElementAt(set.elementAt(index + 1), index); ASN1Encodable eh = t[0], ei = t[1];
set.setElementAt(o, index + 1); byte[] bh = getDEREncoded(eh), bi = getDEREncoded(ei);;
swapped = true; if (lessThanOrEqual(bi, bh))
swapIndex = index; {
ASN1Encodable et = ei; ei = eh; eh = et;
byte[] bt = bi; bi = bh; bh = bt;
} }
index++; for (int i = 2; i < count; ++i)
} {
ASN1Encodable e2 = t[i];
byte[] b2 = getDEREncoded(e2);
lastSwap = swapIndex; if (lessThanOrEqual(bi, b2))
} {
} t[i - 2] = eh;
} eh = ei; bh = bi;
ei = e2; bi = b2;
continue;
} }
boolean isConstructed() if (lessThanOrEqual(bh, b2))
{ {
return true; t[i - 2] = eh;
eh = e2; bh = b2;
continue;
} }
abstract void encode(ASN1OutputStream out) int j = i - 1;
throws IOException; while (--j > 0)
{
ASN1Encodable e1 = t[j - 1];
byte[] b1 = getDEREncoded(e1);
public String toString() if (lessThanOrEqual(b1, b2))
{ {
return set.toString(); break;
} }
public Iterator<ASN1Encodable> iterator() t[j] = e1;
{ }
return new Arrays.Iterator<ASN1Encodable>(toArray());
t[j] = e2;
}
t[count - 2] = eh;
t[count - 1] = ei;
} }
} }

33
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1StreamParser.java

@ -72,9 +72,9 @@ public class ASN1StreamParser
switch (tag) switch (tag)
{ {
case BERTags.SET: case BERTags.SET:
return new DERSetParser(this); return new DLSetParser(this);
case BERTags.SEQUENCE: case BERTags.SEQUENCE:
return new DERSequenceParser(this); return new DLSequenceParser(this);
case BERTags.OCTET_STRING: case BERTags.OCTET_STRING:
return new BEROctetStringParser(this); return new BEROctetStringParser(this);
} }
@ -101,7 +101,7 @@ public class ASN1StreamParser
{ {
// Note: !CONSTRUCTED => IMPLICIT // Note: !CONSTRUCTED => IMPLICIT
DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in; DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray())); return new DLTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
} }
ASN1EncodableVector v = readVector(); ASN1EncodableVector v = readVector();
@ -114,8 +114,8 @@ public class ASN1StreamParser
} }
return v.size() == 1 return v.size() == 1
? new DERTaggedObject(true, tag, v.get(0)) ? new DLTaggedObject(true, tag, v.get(0))
: new DERTaggedObject(false, tag, DERFactory.createSequence(v)); : new DLTaggedObject(false, tag, DLFactory.createSequence(v));
} }
public ASN1Encodable readObject() public ASN1Encodable readObject()
@ -142,7 +142,8 @@ public class ASN1StreamParser
// //
// calculate length // calculate length
// //
int length = ASN1InputStream.readLength(_in, _limit); int length = ASN1InputStream.readLength(_in, _limit,
tagNo == BERTags.OCTET_STRING || tagNo == BERTags.SEQUENCE || tagNo == BERTags.SET || tagNo == BERTags.EXTERNAL);
if (length < 0) // indefinite-length method if (length < 0) // indefinite-length method
{ {
@ -168,11 +169,11 @@ public class ASN1StreamParser
} }
else else
{ {
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length); DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length, _limit);
if ((tag & BERTags.APPLICATION) != 0) if ((tag & BERTags.APPLICATION) != 0)
{ {
return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray()); return new DLApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
} }
if ((tag & BERTags.TAGGED) != 0) if ((tag & BERTags.TAGGED) != 0)
@ -191,9 +192,9 @@ public class ASN1StreamParser
// //
return new BEROctetStringParser(new ASN1StreamParser(defIn)); return new BEROctetStringParser(new ASN1StreamParser(defIn));
case BERTags.SEQUENCE: case BERTags.SEQUENCE:
return new DERSequenceParser(new ASN1StreamParser(defIn)); return new DLSequenceParser(new ASN1StreamParser(defIn));
case BERTags.SET: case BERTags.SET:
return new DERSetParser(new ASN1StreamParser(defIn)); return new DLSetParser(new ASN1StreamParser(defIn));
case BERTags.EXTERNAL: case BERTags.EXTERNAL:
return new DERExternalParser(new ASN1StreamParser(defIn)); return new DERExternalParser(new ASN1StreamParser(defIn));
default: default:
@ -229,10 +230,14 @@ public class ASN1StreamParser
ASN1EncodableVector readVector() throws IOException ASN1EncodableVector readVector() throws IOException
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1Encodable obj = readObject();
if (null == obj)
{
return new ASN1EncodableVector(0);
}
ASN1Encodable obj; ASN1EncodableVector v = new ASN1EncodableVector();
while ((obj = readObject()) != null) do
{ {
if (obj instanceof InMemoryRepresentable) if (obj instanceof InMemoryRepresentable)
{ {
@ -243,7 +248,7 @@ public class ASN1StreamParser
v.add(obj.toASN1Primitive()); v.add(obj.toASN1Primitive());
} }
} }
while ((obj = readObject()) != null);
return v; return v;
} }
} }

87
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1TaggedObject.java

@ -11,10 +11,9 @@ public abstract class ASN1TaggedObject
extends ASN1Primitive extends ASN1Primitive
implements ASN1TaggedObjectParser implements ASN1TaggedObjectParser
{ {
int tagNo; final int tagNo;
boolean empty = false; final boolean explicit;
boolean explicit = true; final ASN1Encodable obj;
ASN1Encodable obj = null;
static public ASN1TaggedObject getInstance( static public ASN1TaggedObject getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,
@ -22,7 +21,7 @@ public abstract class ASN1TaggedObject
{ {
if (explicit) if (explicit)
{ {
return (ASN1TaggedObject)obj.getObject(); return getInstance(obj.getObject());
} }
throw new IllegalArgumentException("implicitly tagged tagged object"); throw new IllegalArgumentException("implicitly tagged tagged object");
@ -65,82 +64,39 @@ public abstract class ASN1TaggedObject
int tagNo, int tagNo,
ASN1Encodable obj) ASN1Encodable obj)
{ {
if (obj instanceof ASN1Choice) if (null == obj)
{ {
this.explicit = true; throw new NullPointerException("'obj' cannot be null");
}
else
{
this.explicit = explicit;
} }
this.tagNo = tagNo; this.tagNo = tagNo;
this.explicit = explicit || (obj instanceof ASN1Choice);
if (this.explicit)
{
this.obj = obj;
}
else
{
ASN1Primitive prim = obj.toASN1Primitive();
if (prim instanceof ASN1Set)
{
ASN1Set s = null;
}
this.obj = obj; this.obj = obj;
} }
}
boolean asn1Equals( boolean asn1Equals(ASN1Primitive other)
ASN1Primitive o)
{ {
if (!(o instanceof ASN1TaggedObject)) if (!(other instanceof ASN1TaggedObject))
{ {
return false; return false;
} }
ASN1TaggedObject other = (ASN1TaggedObject)o; ASN1TaggedObject that = (ASN1TaggedObject)other;
if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit) if (this.tagNo != that.tagNo || this.explicit != that.explicit)
{ {
return false; return false;
} }
if(obj == null) ASN1Primitive p1 = this.obj.toASN1Primitive();
{ ASN1Primitive p2 = that.obj.toASN1Primitive();
if (other.obj != null)
{
return false;
}
}
else
{
if (!(obj.toASN1Primitive().equals(other.obj.toASN1Primitive())))
{
return false;
}
}
return true; return p1 == p2 || p1.asn1Equals(p2);
} }
public int hashCode() public int hashCode()
{ {
int code = tagNo; return tagNo ^ (explicit ? 0x0F : 0xF0) ^ obj.toASN1Primitive().hashCode();
// TODO: actually this is wrong - the problem is that a re-encoded
// object may end up with a different hashCode due to implicit
// tagging. As implicit tagging is ambiguous if a sequence is involved
// it seems the only correct method for both equals and hashCode is to
// compare the encodings...
if (obj != null)
{
code ^= obj.hashCode();
}
return code;
} }
/** /**
@ -167,9 +123,12 @@ public abstract class ASN1TaggedObject
return explicit; return explicit;
} }
/**
* @deprecated Will be removed (always returns false).
*/
public boolean isEmpty() public boolean isEmpty()
{ {
return empty; return false;
} }
/** /**
@ -180,15 +139,10 @@ public abstract class ASN1TaggedObject
* appropriate getInstance method. * appropriate getInstance method.
*/ */
public ASN1Primitive getObject() public ASN1Primitive getObject()
{
if (obj != null)
{ {
return obj.toASN1Primitive(); return obj.toASN1Primitive();
} }
return null;
}
/** /**
* Return the object held in this tagged object as a parser assuming it has * Return the object held in this tagged object as a parser assuming it has
* the type of the passed in tag. If the object doesn't have a parser * the type of the passed in tag. If the object doesn't have a parser
@ -232,8 +186,7 @@ public abstract class ASN1TaggedObject
return new DLTaggedObject(explicit, tagNo, obj); return new DLTaggedObject(explicit, tagNo, obj);
} }
abstract void encode(ASN1OutputStream out) abstract void encode(ASN1OutputStream out, boolean withTag) throws IOException;
throws IOException;
public String toString() public String toString()
{ {

36
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ASN1UTCTime.java

@ -88,7 +88,7 @@ public class ASN1UTCTime
} }
else else
{ {
return new ASN1UTCTime(((ASN1OctetString)o).getOctets()); return new ASN1UTCTime(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -123,7 +123,7 @@ public class ASN1UTCTime
public ASN1UTCTime( public ASN1UTCTime(
Date time) Date time)
{ {
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'"); SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", DateUtil.EN_Locale);
dateF.setTimeZone(new SimpleTimeZone(0,"Z")); dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
@ -151,7 +151,15 @@ public class ASN1UTCTime
ASN1UTCTime( ASN1UTCTime(
byte[] time) byte[] time)
{ {
if (time.length < 2)
{
throw new IllegalArgumentException("UTCTime string too short");
}
this.time = time; this.time = time;
if (!(isDigit(0) && isDigit(1)))
{
throw new IllegalArgumentException("illegal characters in UTCTime string");
}
} }
/** /**
@ -166,7 +174,7 @@ public class ASN1UTCTime
{ {
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz"); SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
return dateF.parse(getTime()); return DateUtil.epochAdjust(dateF.parse(getTime()));
} }
/** /**
@ -183,7 +191,7 @@ public class ASN1UTCTime
dateF.setTimeZone(new SimpleTimeZone(0,"Z")); dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
return dateF.parse(getAdjustedTime()); return DateUtil.epochAdjust(dateF.parse(getAdjustedTime()));
} }
/** /**
@ -263,6 +271,11 @@ public class ASN1UTCTime
} }
} }
private boolean isDigit(int pos)
{
return time.length > pos && time[pos] >= '0' && time[pos] <= '9';
}
boolean isConstructed() boolean isConstructed()
{ {
return false; return false;
@ -275,20 +288,9 @@ public class ASN1UTCTime
return 1 + StreamUtil.calculateBodyLength(length) + length; return 1 + StreamUtil.calculateBodyLength(length) + length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.write(BERTags.UTC_TIME); out.writeEncoded(withTag, BERTags.UTC_TIME, time);
int length = time.length;
out.writeLength(length);
for (int i = 0; i != length; i++)
{
out.write((byte)time[i]);
}
} }
boolean asn1Equals( boolean asn1Equals(

12
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERApplicationSpecific.java

@ -97,18 +97,14 @@ public class BERApplicationSpecific
/* (non-Javadoc) /* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream) * @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream)
*/ */
void encode(ASN1OutputStream out) throws IOException void encode(ASN1OutputStream out, boolean withTag) throws IOException
{ {
int classBits = BERTags.APPLICATION; int flags = BERTags.APPLICATION;
if (isConstructed) if (isConstructed)
{ {
classBits |= BERTags.CONSTRUCTED; flags |= BERTags.CONSTRUCTED;
} }
out.writeTag(classBits, tag); out.writeEncodedIndef(withTag, flags, tag, octets);
out.write(0x80);
out.write(octets);
out.write(0x00);
out.write(0x00);
} }
} }

14
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERFactory.java

@ -7,11 +7,21 @@ class BERFactory
static BERSequence createSequence(ASN1EncodableVector v) static BERSequence createSequence(ASN1EncodableVector v)
{ {
return v.size() < 1 ? EMPTY_SEQUENCE : new BERSequence(v); if (v.size() < 1)
{
return EMPTY_SEQUENCE;
}
return new BERSequence(v);
} }
static BERSet createSet(ASN1EncodableVector v) static BERSet createSet(ASN1EncodableVector v)
{ {
return v.size() < 1 ? EMPTY_SET : new BERSet(v); if (v.size() < 1)
{
return EMPTY_SET;
}
return new BERSet(v);
} }
} }

33
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BEROctetString.java

@ -191,37 +191,28 @@ public class BEROctetString
return 2 + length + 2; return 2 + length + 2;
} }
public void encode( /**
ASN1OutputStream out) * @deprecated
*/
public void encode(ASN1OutputStream out)
throws IOException throws IOException
{ {
out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING); out.writeObject(this);
out.write(0x80);
//
// write out the octet array
//
for (Enumeration e = getObjects(); e.hasMoreElements();)
{
out.writeObject((ASN1Encodable)e.nextElement());
} }
out.write(0x00); void encode(ASN1OutputStream out, boolean withTag) throws IOException
out.write(0x00); {
out.writeEncodedIndef(withTag, BERTags.CONSTRUCTED | BERTags.OCTET_STRING, getObjects());
} }
static BEROctetString fromSequence(ASN1Sequence seq) static BEROctetString fromSequence(ASN1Sequence seq)
{ {
ASN1OctetString[] v = new ASN1OctetString[seq.size()]; int count = seq.size();
Enumeration e = seq.getObjects(); ASN1OctetString[] v = new ASN1OctetString[count];
int index = 0; for (int i = 0; i < count; ++i)
while (e.hasMoreElements())
{ {
v[index++] = (ASN1OctetString)e.nextElement(); v[i] = ASN1OctetString.getInstance(seq.getObjectAt(i));
} }
return new BEROctetString(v); return new BEROctetString(v);
} }
} }

11
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BEROctetStringGenerator.java

@ -89,7 +89,7 @@ public class BEROctetStringGenerator
if (_off == _buf.length) if (_off == _buf.length)
{ {
DEROctetString.encode(_derOut, _buf); DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
_off = 0; _off = 0;
} }
} }
@ -107,7 +107,7 @@ public class BEROctetStringGenerator
break; break;
} }
DEROctetString.encode(_derOut, _buf); DEROctetString.encode(_derOut, true, _buf, 0, _buf.length);
_off = 0; _off = 0;
off += numToCopy; off += numToCopy;
@ -120,12 +120,11 @@ public class BEROctetStringGenerator
{ {
if (_off != 0) if (_off != 0)
{ {
byte[] bytes = new byte[_off]; DEROctetString.encode(_derOut, true, _buf, 0, _off);
System.arraycopy(_buf, 0, bytes, 0, _off);
DEROctetString.encode(_derOut, bytes);
} }
_derOut.flushInternal();
writeBEREnd(); writeBEREnd();
} }
} }

46
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BEROutputStream.java

@ -1,51 +1,27 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException;
import java.io.OutputStream; 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 * A class which writes indefinite and definite length objects. Objects which specify DER will be
* objects will be encoded as defined. * encoded accordingly, but DL or BER objects will be encoded as defined.
*
* @deprecated Will be removed from public API.
*/ */
public class BEROutputStream public class BEROutputStream
extends DEROutputStream extends ASN1OutputStream
{ {
/** /**
* Base constructor. * Base constructor.
* *
* @param os target output stream. * @param os
*/ * target output stream.
public BEROutputStream(
OutputStream os)
{
super(os);
}
/**
* Write out an ASN.1 object.
* *
* @param obj the object to be encoded. * @deprecated Use {@link ASN1OutputStream#create(OutputStream, String)} with
* @throws IOException if there is an issue on encoding or output of the object. * {@link ASN1Encoding#BER} instead.
*/ */
public void writeObject( public BEROutputStream(OutputStream os)
Object obj)
throws IOException
{
if (obj == null)
{ {
writeNull(); super(os);
}
else if (obj instanceof ASN1Primitive)
{
((ASN1Primitive)obj).encode(this);
}
else if (obj instanceof ASN1Encodable)
{
((ASN1Encodable)obj).toASN1Primitive().encode(this);
}
else
{
throw new IOException("object not BEREncodable");
}
} }
} }

46
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERSequence.java

@ -1,7 +1,6 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration;
/** /**
* Indefinite length SEQUENCE of objects. * Indefinite length SEQUENCE of objects.
@ -24,56 +23,43 @@ public class BERSequence
/** /**
* Create a sequence containing one object * Create a sequence containing one object
*/ */
public BERSequence( public BERSequence(ASN1Encodable element)
ASN1Encodable obj)
{ {
super(obj); super(element);
} }
/** /**
* Create a sequence containing a vector of objects. * Create a sequence containing a vector of objects.
*/ */
public BERSequence( public BERSequence(ASN1EncodableVector elementVector)
ASN1EncodableVector v)
{ {
super(v); super(elementVector);
} }
/** /**
* Create a sequence containing an array of objects. * Create a sequence containing an array of objects.
*/ */
public BERSequence( public BERSequence(ASN1Encodable[] elements)
ASN1Encodable[] array)
{ {
super(array); super(elements);
} }
int encodedLength() int encodedLength() throws IOException
throws IOException
{ {
int length = 0; int count = elements.length;
for (Enumeration e = getObjects(); e.hasMoreElements();) int totalLength = 0;
for (int i = 0; i < count; ++i)
{ {
length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength(); ASN1Primitive p = elements[i].toASN1Primitive();
totalLength += p.encodedLength();
} }
return 2 + length + 2; return 2 + totalLength + 2;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{
out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
out.write(0x80);
Enumeration e = getObjects();
while (e.hasMoreElements())
{ {
out.writeObject((ASN1Encodable)e.nextElement()); out.writeEncodedIndef(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, elements);
}
out.write(0x00);
out.write(0x00);
} }
} }

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERSequenceGenerator.java

@ -55,7 +55,7 @@ public class BERSequenceGenerator
ASN1Encodable object) ASN1Encodable object)
throws IOException throws IOException
{ {
object.toASN1Primitive().encode(new BEROutputStream(_out)); object.toASN1Primitive().encodeTo(_out);
} }
/** /**

55
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERSet.java

@ -1,7 +1,6 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration;
/** /**
* Indefinite length <code>SET</code> and <code>SET OF</code> constructs. * Indefinite length <code>SET</code> and <code>SET OF</code> constructs.
@ -30,60 +29,52 @@ public class BERSet
/** /**
* Create a SET containing one object. * Create a SET containing one object.
* *
* @param obj - a single object that makes up the set. * @param element - a single object that makes up the set.
*/ */
public BERSet( public BERSet(ASN1Encodable element)
ASN1Encodable obj)
{ {
super(obj); super(element);
} }
/** /**
* Create a SET containing multiple objects. * Create a SET containing multiple objects.
* @param v a vector of objects making up the set. * @param elementVector a vector of objects making up the set.
*/ */
public BERSet( public BERSet(ASN1EncodableVector elementVector)
ASN1EncodableVector v)
{ {
super(v, false); super(elementVector, false);
} }
/** /**
* Create a SET from an array of objects. * Create a SET from an array of objects.
* @param a an array of ASN.1 objects. * @param elements an array of ASN.1 objects.
*/ */
public BERSet( public BERSet(ASN1Encodable[] elements)
ASN1Encodable[] a)
{ {
super(a, false); super(elements, false);
} }
int encodedLength() BERSet(boolean isSorted, ASN1Encodable[] elements)
throws IOException
{ {
int length = 0; super(isSorted, elements);
for (Enumeration e = getObjects(); e.hasMoreElements();)
{
length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
}
return 2 + length + 2;
} }
void encode( int encodedLength() throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.write(BERTags.SET | BERTags.CONSTRUCTED); int count = elements.length;
out.write(0x80); int totalLength = 0;
Enumeration e = getObjects(); for (int i = 0; i < count; ++i)
while (e.hasMoreElements())
{ {
out.writeObject((ASN1Encodable)e.nextElement()); ASN1Primitive p = elements[i].toASN1Primitive();
totalLength += p.encodedLength();
} }
out.write(0x00); return 2 + totalLength + 2;
out.write(0x00); }
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
out.writeEncodedIndef(withTag, BERTags.SET | BERTags.CONSTRUCTED, elements);
} }
} }

63
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/BERTaggedObject.java

@ -47,29 +47,11 @@ public class BERTaggedObject
boolean isConstructed() boolean isConstructed()
{ {
if (!empty) return explicit || obj.toASN1Primitive().isConstructed();
{
if (explicit)
{
return true;
}
else
{
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
return primitive.isConstructed();
}
}
else
{
return true;
}
} }
int encodedLength() int encodedLength()
throws IOException throws IOException
{
if (!empty)
{ {
ASN1Primitive primitive = obj.toASN1Primitive(); ASN1Primitive primitive = obj.toASN1Primitive();
int length = primitive.encodedLength(); int length = primitive.encodedLength();
@ -86,21 +68,12 @@ public class BERTaggedObject
return StreamUtil.calculateTagLength(tagNo) + length; return StreamUtil.calculateTagLength(tagNo) + length;
} }
} }
else
{
return StreamUtil.calculateTagLength(tagNo) + 1;
}
}
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); out.writeTag(withTag, BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
out.write(0x80); out.write(0x80);
if (!empty)
{
if (!explicit) if (!explicit)
{ {
Enumeration e; Enumeration e;
@ -130,18 +103,36 @@ public class BERTaggedObject
throw new ASN1Exception("not implemented: " + obj.getClass().getName()); throw new ASN1Exception("not implemented: " + obj.getClass().getName());
} }
while (e.hasMoreElements()) out.writeElements(e);
{
out.writeObject((ASN1Encodable)e.nextElement());
}
} }
else else
{ {
out.writeObject(obj); out.writePrimitive(obj.toASN1Primitive(), true);
}
} }
out.write(0x00); out.write(0x00);
out.write(0x00); out.write(0x00);
// ASN1Primitive primitive = obj.toASN1Primitive();
//
// int flags = BERTags.TAGGED;
// if (explicit || primitive.isConstructed())
// {
// flags |= BERTags.CONSTRUCTED;
// }
//
// out.writeTag(withTag, flags, tagNo);
//
// if (explicit)
// {
// out.write(0x80);
// out.writePrimitive(obj.toASN1Primitive(), true);
// out.write(0x00);
// out.write(0x00);
// }
// else
// {
// out.writePrimitive(obj.toASN1Primitive(), false);
// }
} }
} }

45
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/ConstructedOctetStream.java

@ -26,13 +26,19 @@ class ConstructedOctetStream
return -1; return -1;
} }
ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject(); ASN1Encodable asn1Obj = _parser.readObject();
if (asn1Obj == null)
if (s == null)
{ {
return -1; return -1;
} }
if (!(asn1Obj instanceof ASN1OctetStringParser))
{
throw new IOException("unknown object encountered: " + asn1Obj.getClass());
}
ASN1OctetStringParser s = (ASN1OctetStringParser)asn1Obj;
_first = false; _first = false;
_currentStream = s.getOctetStream(); _currentStream = s.getOctetStream();
} }
@ -54,14 +60,21 @@ class ConstructedOctetStream
} }
else else
{ {
ASN1OctetStringParser aos = (ASN1OctetStringParser)_parser.readObject(); ASN1Encodable asn1Obj = _parser.readObject();
if (aos == null) if (asn1Obj == null)
{ {
_currentStream = null; _currentStream = null;
return totalRead < 1 ? -1 : totalRead; return totalRead < 1 ? -1 : totalRead;
} }
if (!(asn1Obj instanceof ASN1OctetStringParser))
{
throw new IOException("unknown object encountered: " + asn1Obj.getClass());
}
ASN1OctetStringParser aos = (ASN1OctetStringParser)asn1Obj;
_currentStream = aos.getOctetStream(); _currentStream = aos.getOctetStream();
} }
} }
@ -77,13 +90,20 @@ class ConstructedOctetStream
return -1; return -1;
} }
ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject(); ASN1Encodable asn1Obj = _parser.readObject();
if (s == null) if (asn1Obj == null)
{ {
return -1; return -1;
} }
if (!(asn1Obj instanceof ASN1OctetStringParser))
{
throw new IOException("unknown object encountered: " + asn1Obj.getClass());
}
ASN1OctetStringParser s = (ASN1OctetStringParser)asn1Obj;
_first = false; _first = false;
_currentStream = s.getOctetStream(); _currentStream = s.getOctetStream();
} }
@ -97,14 +117,21 @@ class ConstructedOctetStream
return b; return b;
} }
ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject(); ASN1Encodable asn1Obj = _parser.readObject();
if (s == null) if (asn1Obj == null)
{ {
_currentStream = null; _currentStream = null;
return -1; return -1;
} }
if (!(asn1Obj instanceof ASN1OctetStringParser))
{
throw new IOException("unknown object encountered: " + asn1Obj.getClass());
}
ASN1OctetStringParser s = (ASN1OctetStringParser)asn1Obj;
_currentStream = s.getOctetStream(); _currentStream = s.getOctetStream();
} }
} }

35
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERApplicationSpecific.java

@ -3,8 +3,6 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import com.fr.third.org.bouncycastle.util.encoders.Hex;
/** /**
* A DER encoding version of an application specific object. * A DER encoding version of an application specific object.
*/ */
@ -113,39 +111,14 @@ public class DERApplicationSpecific
/* (non-Javadoc) /* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream) * @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream)
*/ */
void encode(ASN1OutputStream out) throws IOException void encode(ASN1OutputStream out, boolean withTag) throws IOException
{ {
int classBits = BERTags.APPLICATION; int flags = BERTags.APPLICATION;
if (isConstructed) if (isConstructed)
{ {
classBits |= BERTags.CONSTRUCTED; flags |= BERTags.CONSTRUCTED;
}
out.writeEncoded(classBits, tag, octets);
} }
public String toString() out.writeEncoded(withTag, flags, tag, octets);
{
StringBuffer sb = new StringBuffer();
sb.append("[");
if (isConstructed())
{
sb.append("CONSTRUCTED ");
}
sb.append("APPLICATION ");
sb.append(Integer.toString(getApplicationTag()));
sb.append("]");
// @todo content encoding somehow?
if (this.octets != null)
{
sb.append(" #");
sb.append(Hex.toHexString(this.octets));
}
else
{
sb.append(" #null");
}
sb.append(" ");
return sb.toString();
} }
} }

43
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERBMPString.java

@ -145,18 +145,49 @@ public class DERBMPString
} }
void encode( void encode(
ASN1OutputStream out) ASN1OutputStream out, boolean withTag)
throws IOException throws IOException
{
int count = string.length;
if (withTag)
{ {
out.write(BERTags.BMP_STRING); out.write(BERTags.BMP_STRING);
out.writeLength(string.length * 2); }
out.writeLength(count * 2);
byte[] buf = new byte[8];
int i = 0, limit = count & -4;
while (i < limit)
{
char c0 = string[i], c1 = string[i + 1], c2 = string[i + 2], c3 = string[i + 3];
i += 4;
for (int i = 0; i != string.length; i++) buf[0] = (byte)(c0 >> 8);
buf[1] = (byte)c0;
buf[2] = (byte)(c1 >> 8);
buf[3] = (byte)c1;
buf[4] = (byte)(c2 >> 8);
buf[5] = (byte)c2;
buf[6] = (byte)(c3 >> 8);
buf[7] = (byte)c3;
out.write(buf, 0, 8);
}
if (i < count)
{
int bufPos = 0;
do
{ {
char c = string[i]; char c0 = string[i];
i += 1;
buf[bufPos++] = (byte)(c0 >> 8);
buf[bufPos++] = (byte)c0;
}
while (i < count);
out.write((byte)(c >> 8)); out.write(buf, 0, bufPos);
out.write((byte)c);
} }
} }
} }

46
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERBitString.java

@ -63,24 +63,13 @@ public class DERBitString
} }
else else
{ {
return fromOctetString(((ASN1OctetString)o).getOctets()); return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
} }
} }
protected DERBitString( protected DERBitString(byte data, int padBits)
byte data,
int padBits)
{ {
this(toByteArray(data), padBits); super(data, padBits);
}
private static byte[] toByteArray(byte data)
{
byte[] rv = new byte[1];
rv[0] = data;
return rv;
} }
/** /**
@ -123,17 +112,30 @@ public class DERBitString
return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1; return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out) {
throws IOException int len = data.length;
if (0 == len
|| 0 == padBits
|| (data[len - 1] == (byte)(data[len - 1] & (0xFF << padBits))))
{ {
byte[] string = derForm(data, padBits); out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
byte[] bytes = new byte[string.length + 1]; }
else
{
byte der = (byte)(data[len - 1] & (0xFF << padBits));
out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data, 0, len - 1, der);
}
}
bytes[0] = (byte)getPadBits(); ASN1Primitive toDERObject()
System.arraycopy(string, 0, bytes, 1, bytes.length - 1); {
return this;
}
out.writeEncoded(BERTags.BIT_STRING, bytes); ASN1Primitive toDLObject()
{
return this;
} }
static DERBitString fromOctetString(byte[] bytes) static DERBitString fromOctetString(byte[] bytes)

22
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERBoolean.java

@ -1,22 +0,0 @@
package com.fr.third.org.bouncycastle.asn1;
/**
* @deprecated use ASN1Boolean
*/
public class DERBoolean
extends ASN1Boolean
{
/**
* @deprecated use getInstance(boolean) method.
* @param value
*/
public DERBoolean(boolean value)
{
super(value);
}
DERBoolean(byte[] value)
{
super(value);
}
}

229
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERExternal.java

@ -7,14 +7,8 @@ import java.io.IOException;
* Class representing the DER-type External * Class representing the DER-type External
*/ */
public class DERExternal public class DERExternal
extends ASN1Primitive extends ASN1External
{ {
private ASN1ObjectIdentifier directReference;
private ASN1Integer indirectReference;
private ASN1Primitive dataValueDescriptor;
private int encoding;
private ASN1Primitive externalContent;
/** /**
* Construct a DER EXTERNAL object, the input encoding vector must have exactly two elements on it. * Construct a DER EXTERNAL object, the input encoding vector must have exactly two elements on it.
* <p> * <p>
@ -29,51 +23,9 @@ public class DERExternal
*/ */
public DERExternal(ASN1EncodableVector vector) public DERExternal(ASN1EncodableVector vector)
{ {
int offset = 0; super(vector);
ASN1Primitive enc = getObjFromVector(vector, offset);
if (enc instanceof ASN1ObjectIdentifier)
{
directReference = (ASN1ObjectIdentifier)enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (enc instanceof ASN1Integer)
{
indirectReference = (ASN1Integer) enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (!(enc instanceof ASN1TaggedObject))
{
dataValueDescriptor = (ASN1Primitive) enc;
offset++;
enc = getObjFromVector(vector, offset);
}
if (vector.size() != offset + 1)
{
throw new IllegalArgumentException("input vector too large");
}
if (!(enc instanceof ASN1TaggedObject))
{
throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
}
ASN1TaggedObject obj = (ASN1TaggedObject)enc;
setEncoding(obj.getTagNo());
externalContent = obj.getObject();
}
private ASN1Primitive getObjFromVector(ASN1EncodableVector v, int index)
{
if (v.size() <= index)
{
throw new IllegalArgumentException("too few objects in input vector");
} }
return v.get(index).toASN1Primitive();
}
/** /**
* Creates a new instance of DERExternal * Creates a new instance of DERExternal
* See X.690 for more informations about the meaning of these parameters * See X.690 for more informations about the meaning of these parameters
@ -98,38 +50,17 @@ public class DERExternal
*/ */
public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData) public DERExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{ {
setDirectReference(directReference); super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
setIndirectReference(indirectReference);
setDataValueDescriptor(dataValueDescriptor);
setEncoding(encoding);
setExternalContent(externalData.toASN1Primitive());
} }
/* (non-Javadoc) ASN1Primitive toDERObject()
* @see java.lang.Object#hashCode()
*/
public int hashCode()
{ {
int ret = 0; return this;
if (directReference != null)
{
ret = directReference.hashCode();
}
if (indirectReference != null)
{
ret ^= indirectReference.hashCode();
}
if (dataValueDescriptor != null)
{
ret ^= dataValueDescriptor.hashCode();
}
ret ^= externalContent.hashCode();
return ret;
} }
boolean isConstructed() ASN1Primitive toDLObject()
{ {
return true; return this;
} }
int encodedLength() int encodedLength()
@ -141,8 +72,7 @@ public class DERExternal
/* (non-Javadoc) /* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream) * @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream)
*/ */
void encode(ASN1OutputStream out) void encode(ASN1OutputStream out, boolean withTag) throws IOException
throws IOException
{ {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (directReference != null) if (directReference != null)
@ -159,148 +89,7 @@ public class DERExternal
} }
DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent); DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
baos.write(obj.getEncoded(ASN1Encoding.DER)); baos.write(obj.getEncoded(ASN1Encoding.DER));
out.writeEncoded(BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
}
/* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#asn1Equals(com.fr.third.org.bouncycastle.asn1.ASN1Primitive)
*/
boolean asn1Equals(ASN1Primitive o)
{
if (!(o instanceof DERExternal))
{
return false;
}
if (this == o)
{
return true;
}
DERExternal other = (DERExternal)o;
if (directReference != null)
{
if (other.directReference == null || !other.directReference.equals(directReference))
{
return false;
}
}
if (indirectReference != null)
{
if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
{
return false;
}
}
if (dataValueDescriptor != null)
{
if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
{
return false;
}
}
return externalContent.equals(other.externalContent);
}
/**
* Returns the data value descriptor
* @return The descriptor
*/
public ASN1Primitive getDataValueDescriptor()
{
return dataValueDescriptor;
}
/**
* Returns the direct reference of the external element
* @return The reference
*/
public ASN1ObjectIdentifier getDirectReference()
{
return directReference;
}
/**
* Returns the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
* @return The encoding
*/
public int getEncoding()
{
return encoding;
}
/**
* Returns the content of this element
* @return The content
*/
public ASN1Primitive getExternalContent()
{
return externalContent;
}
/**
* Returns the indirect reference of this element
* @return The reference
*/
public ASN1Integer getIndirectReference()
{
return indirectReference;
}
/** out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
* Sets the data value descriptor
* @param dataValueDescriptor The descriptor
*/
private void setDataValueDescriptor(ASN1Primitive dataValueDescriptor)
{
this.dataValueDescriptor = dataValueDescriptor;
}
/**
* Sets the direct reference of the external element
* @param directReferemce The reference
*/
private void setDirectReference(ASN1ObjectIdentifier directReferemce)
{
this.directReference = directReferemce;
}
/**
* Sets the encoding of the content. Valid values are
* <ul>
* <li><code>0</code> single-ASN1-type</li>
* <li><code>1</code> OCTET STRING</li>
* <li><code>2</code> BIT STRING</li>
* </ul>
* @param encoding The encoding
*/
private void setEncoding(int encoding)
{
if (encoding < 0 || encoding > 2)
{
throw new IllegalArgumentException("invalid encoding value: " + encoding);
}
this.encoding = encoding;
}
/**
* Sets the content of this element
* @param externalContent The content
*/
private void setExternalContent(ASN1Primitive externalContent)
{
this.externalContent = externalContent;
}
/**
* Sets the indirect reference of this element
* @param indirectReference The reference
*/
private void setIndirectReference(ASN1Integer indirectReference)
{
this.indirectReference = indirectReference;
} }
} }

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERExternalParser.java

@ -37,7 +37,7 @@ public class DERExternalParser
{ {
try try
{ {
return new DERExternal(_parser.readVector()); return new DLExternal(_parser.readVector());
} }
catch (IllegalArgumentException e) catch (IllegalArgumentException e)
{ {

14
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERFactory.java

@ -7,11 +7,21 @@ class DERFactory
static ASN1Sequence createSequence(ASN1EncodableVector v) static ASN1Sequence createSequence(ASN1EncodableVector v)
{ {
return v.size() < 1 ? EMPTY_SEQUENCE : new DLSequence(v); if (v.size() < 1)
{
return EMPTY_SEQUENCE;
}
return new DERSequence(v);
} }
static ASN1Set createSet(ASN1EncodableVector v) static ASN1Set createSet(ASN1EncodableVector v)
{ {
return v.size() < 1 ? EMPTY_SET : new DLSet(v); if (v.size() < 1)
{
return EMPTY_SET;
}
return new DERSet(v);
} }
} }

7
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERGeneralString.java

@ -71,7 +71,7 @@ public class DERGeneralString
} }
else else
{ {
return new DERGeneralString(((ASN1OctetString)o).getOctets()); return new DERGeneralString(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -125,10 +125,9 @@ public class DERGeneralString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode(ASN1OutputStream out) void encode(ASN1OutputStream out, boolean withTag) throws IOException
throws IOException
{ {
out.writeEncoded(BERTags.GENERAL_STRING, string); out.writeEncoded(withTag, BERTags.GENERAL_STRING, string);
} }
public int hashCode() public int hashCode()

16
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERGeneralizedTime.java

@ -107,10 +107,18 @@ public class DERGeneralizedTime
return 1 + StreamUtil.calculateBodyLength(length) + length; return 1 + StreamUtil.calculateBodyLength(length) + length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.GENERALIZED_TIME, getDERTime()); out.writeEncoded(withTag, BERTags.GENERALIZED_TIME, getDERTime());
}
ASN1Primitive toDERObject()
{
return this;
}
ASN1Primitive toDLObject()
{
return this;
} }
} }

8
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERGraphicString.java

@ -63,7 +63,7 @@ public class DERGraphicString
} }
else else
{ {
return new DERGraphicString(((ASN1OctetString)o).getOctets()); return new DERGraphicString(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -92,11 +92,9 @@ public class DERGraphicString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.GRAPHIC_STRING, string); out.writeEncoded(withTag, BERTags.GRAPHIC_STRING, string);
} }
public int hashCode() public int hashCode()

12
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERIA5String.java

@ -69,7 +69,7 @@ public class DERIA5String
} }
else else
{ {
return new DERIA5String(((ASN1OctetString)o).getOctets()); return new DERIA5String(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -107,11 +107,11 @@ public class DERIA5String
{ {
if (string == null) if (string == null)
{ {
throw new NullPointerException("string cannot be null"); throw new NullPointerException("'string' cannot be null");
} }
if (validate && !isIA5String(string)) if (validate && !isIA5String(string))
{ {
throw new IllegalArgumentException("string contains illegal characters"); throw new IllegalArgumentException("'string' contains illegal characters");
} }
this.string = Strings.toByteArray(string); this.string = Strings.toByteArray(string);
@ -142,11 +142,9 @@ public class DERIA5String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.IA5_STRING, string); out.writeEncoded(withTag, BERTags.IA5_STRING, string);
} }
public int hashCode() public int hashCode()

6
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERNull.java

@ -31,10 +31,8 @@ public class DERNull
return 2; return 2;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.NULL, zeroBytes); out.writeEncoded(withTag, BERTags.NULL, zeroBytes);
} }
} }

6
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERNumericString.java

@ -140,11 +140,9 @@ public class DERNumericString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.NUMERIC_STRING, string); out.writeEncoded(withTag, BERTags.NUMERIC_STRING, string);
} }
public int hashCode() public int hashCode()

23
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DEROctetString.java

@ -41,18 +41,23 @@ public class DEROctetString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.OCTET_STRING, string); out.writeEncoded(withTag, BERTags.OCTET_STRING, string);
} }
static void encode( ASN1Primitive toDERObject()
DEROutputStream derOut, {
byte[] bytes) return this;
throws IOException }
ASN1Primitive toDLObject()
{
return this;
}
static void encode(ASN1OutputStream derOut, boolean withTag, byte[] buf, int off, int len) throws IOException
{ {
derOut.writeEncoded(BERTags.OCTET_STRING, bytes); derOut.writeEncoded(withTag, BERTags.OCTET_STRING, buf, off, len);
} }
} }

24
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DEROutputStream.java

@ -5,31 +5,27 @@ import java.io.OutputStream;
/** /**
* Stream that outputs encoding based on distinguished encoding rules. * Stream that outputs encoding based on distinguished encoding rules.
*
* @deprecated Will be removed from public API.
*/ */
public class DEROutputStream public class DEROutputStream
extends ASN1OutputStream extends ASN1OutputStream
{ {
public DEROutputStream( /**
OutputStream os) * @deprecated Use {@link ASN1OutputStream#create(OutputStream, String)} with
* {@link ASN1Encoding#DER} instead.
*/
public DEROutputStream(OutputStream os)
{ {
super(os); super(os);
} }
public void writeObject( void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
ASN1Encodable obj)
throws IOException
{
if (obj != null)
{ {
obj.toASN1Primitive().toDERObject().encode(this); primitive.toDERObject().encode(this, withTag);
}
else
{
throw new IOException("null object detected");
}
} }
ASN1OutputStream getDERSubStream() DEROutputStream getDERSubStream()
{ {
return this; return this;
} }

6
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERPrintableString.java

@ -151,11 +151,9 @@ public class DERPrintableString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.PRINTABLE_STRING, string); out.writeEncoded(withTag, BERTags.PRINTABLE_STRING, string);
} }
public int hashCode() public int hashCode()

105
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSequence.java

@ -1,7 +1,7 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.io.OutputStream;
/** /**
* Definite length SEQUENCE, encoding tells explicit number of bytes * Definite length SEQUENCE, encoding tells explicit number of bytes
@ -12,6 +12,11 @@ import java.util.Enumeration;
public class DERSequence public class DERSequence
extends ASN1Sequence extends ASN1Sequence
{ {
public static DERSequence convert(ASN1Sequence seq)
{
return (DERSequence)seq.toDERObject();
}
private int bodyLength = -1; private int bodyLength = -1;
/** /**
@ -23,56 +28,56 @@ public class DERSequence
/** /**
* Create a sequence containing one object * Create a sequence containing one object
* @param obj the object to go in the sequence. * @param element the object to go in the sequence.
*/ */
public DERSequence( public DERSequence(ASN1Encodable element)
ASN1Encodable obj)
{ {
super(obj); super(element);
} }
/** /**
* Create a sequence containing a vector of objects. * Create a sequence containing a vector of objects.
* @param v the vector of objects to make up the sequence. * @param elementVector the vector of objects to make up the sequence.
*/ */
public DERSequence( public DERSequence(ASN1EncodableVector elementVector)
ASN1EncodableVector v)
{ {
super(v); super(elementVector);
} }
/** /**
* Create a sequence containing an array of objects. * Create a sequence containing an array of objects.
* @param array the array of objects to make up the sequence. * @param elements the array of objects to make up the sequence.
*/ */
public DERSequence( public DERSequence(ASN1Encodable[] elements)
ASN1Encodable[] array) {
super(elements);
}
DERSequence(ASN1Encodable[] elements, boolean clone)
{ {
super(array); super(elements, clone);
} }
private int getBodyLength() private int getBodyLength() throws IOException
throws IOException
{ {
if (bodyLength < 0) if (bodyLength < 0)
{ {
int length = 0; int count = elements.length;
int totalLength = 0;
for (Enumeration e = this.getObjects(); e.hasMoreElements();) for (int i = 0; i < count; ++i)
{ {
Object obj = e.nextElement(); ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
totalLength += derObject.encodedLength();
length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
} }
bodyLength = length; this.bodyLength = totalLength;
} }
return bodyLength; return bodyLength;
} }
int encodedLength() int encodedLength() throws IOException
throws IOException
{ {
int length = getBodyLength(); int length = getBodyLength();
@ -87,21 +92,55 @@ public class DERSequence
* ASN.1 descriptions given. Rather than just outputting SEQUENCE, * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
* we also have to specify CONSTRUCTED, and the objects length. * we also have to specify CONSTRUCTED, and the objects length.
*/ */
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out) {
throws IOException if (withTag)
{ {
ASN1OutputStream dOut = out.getDERSubStream();
int length = getBodyLength();
out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED); out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
out.writeLength(length); }
DEROutputStream derOut = out.getDERSubStream();
for (Enumeration e = this.getObjects(); e.hasMoreElements();) int count = elements.length;
if (bodyLength >= 0 || count > 16)
{ {
Object obj = e.nextElement(); out.writeLength(getBodyLength());
dOut.writeObject((ASN1Encodable)obj); for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObject.encode(derOut, true);
}
} }
else
{
int totalLength = 0;
ASN1Primitive[] derObjects = new ASN1Primitive[count];
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
totalLength += derObject.encodedLength();
}
this.bodyLength = totalLength;
out.writeLength(totalLength);
for (int i = 0; i < count; ++i)
{
derObjects[i].encode(derOut, true);
}
}
}
ASN1Primitive toDERObject()
{
return this;
}
ASN1Primitive toDLObject()
{
return this;
} }
} }

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSequenceGenerator.java

@ -53,7 +53,7 @@ public class DERSequenceGenerator
ASN1Encodable object) ASN1Encodable object)
throws IOException throws IOException
{ {
object.toASN1Primitive().encode(new DEROutputStream(_bOut)); object.toASN1Primitive().encodeTo(_bOut, ASN1Encoding.DER);
} }
/** /**

4
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSequenceParser.java

@ -3,7 +3,7 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
/** /**
* Parser class for DER SEQUENCEs. * @deprecated Use DLSequenceParser instead
*/ */
public class DERSequenceParser public class DERSequenceParser
implements ASN1SequenceParser implements ASN1SequenceParser
@ -36,7 +36,7 @@ public class DERSequenceParser
public ASN1Primitive getLoadedObject() public ASN1Primitive getLoadedObject()
throws IOException throws IOException
{ {
return new DERSequence(_parser.readVector()); return new DLSequence(_parser.readVector());
} }
/** /**

115
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSet.java

@ -1,7 +1,7 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.io.OutputStream;
/** /**
* A DER encoded SET object * A DER encoded SET object
@ -16,6 +16,11 @@ import java.util.Enumeration;
public class DERSet public class DERSet
extends ASN1Set extends ASN1Set
{ {
public static DERSet convert(ASN1Set set)
{
return (DERSet)set.toDERObject();
}
private int bodyLength = -1; private int bodyLength = -1;
/** /**
@ -27,63 +32,56 @@ public class DERSet
/** /**
* create a set containing one object * create a set containing one object
* @param obj the object to go in the set * @param element the object to go in the set
*/ */
public DERSet( public DERSet(ASN1Encodable element)
ASN1Encodable obj)
{ {
super(obj); super(element);
} }
/** /**
* create a set containing a vector of objects. * create a set containing a vector of objects.
* @param v the vector of objects to make up the set. * @param elementVector the vector of objects to make up the set.
*/ */
public DERSet( public DERSet(ASN1EncodableVector elementVector)
ASN1EncodableVector v)
{ {
super(v, true); super(elementVector, true);
} }
/** /**
* create a set containing an array of objects. * create a set containing an array of objects.
* @param a the array of objects to make up the set. * @param elements the array of objects to make up the set.
*/ */
public DERSet( public DERSet(ASN1Encodable[] elements)
ASN1Encodable[] a)
{ {
super(a, true); super(elements, true);
} }
DERSet( DERSet(boolean isSorted, ASN1Encodable[] elements)
ASN1EncodableVector v,
boolean doSort)
{ {
super(v, doSort); super(checkSorted(isSorted), elements);
} }
private int getBodyLength() private int getBodyLength() throws IOException
throws IOException
{ {
if (bodyLength < 0) if (bodyLength < 0)
{ {
int length = 0; int count = elements.length;
int totalLength = 0;
for (Enumeration e = this.getObjects(); e.hasMoreElements();) for (int i = 0; i < count; ++i)
{ {
Object obj = e.nextElement(); ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
totalLength += derObject.encodedLength();
length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
} }
bodyLength = length; this.bodyLength = totalLength;
} }
return bodyLength; return bodyLength;
} }
int encodedLength() int encodedLength() throws IOException
throws IOException
{ {
int length = getBodyLength(); int length = getBodyLength();
@ -98,21 +96,64 @@ public class DERSet
* ASN.1 descriptions given. Rather than just outputting SET, * ASN.1 descriptions given. Rather than just outputting SET,
* we also have to specify CONSTRUCTED, and the objects length. * we also have to specify CONSTRUCTED, and the objects length.
*/ */
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out) {
throws IOException if (withTag)
{ {
ASN1OutputStream dOut = out.getDERSubStream();
int length = getBodyLength();
out.write(BERTags.SET | BERTags.CONSTRUCTED); out.write(BERTags.SET | BERTags.CONSTRUCTED);
out.writeLength(length); }
for (Enumeration e = this.getObjects(); e.hasMoreElements();) DEROutputStream derOut = out.getDERSubStream();
int count = elements.length;
if (bodyLength >= 0 || count > 16)
{
out.writeLength(getBodyLength());
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObject.encode(derOut, true);
}
}
else
{ {
Object obj = e.nextElement(); int totalLength = 0;
dOut.writeObject((ASN1Encodable)obj); ASN1Primitive[] derObjects = new ASN1Primitive[count];
for (int i = 0; i < count; ++i)
{
ASN1Primitive derObject = elements[i].toASN1Primitive().toDERObject();
derObjects[i] = derObject;
totalLength += derObject.encodedLength();
}
this.bodyLength = totalLength;
out.writeLength(totalLength);
for (int i = 0; i < count; ++i)
{
derObjects[i].encode(derOut, true);
}
}
}
ASN1Primitive toDERObject()
{
return isSorted ? this : super.toDERObject();
}
ASN1Primitive toDLObject()
{
return this;
}
private static boolean checkSorted(boolean isSorted)
{
if (!isSorted)
{
throw new IllegalStateException("DERSet elements should always be in sorted order");
} }
return isSorted;
} }
} }

4
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERSetParser.java

@ -3,7 +3,7 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
/** /**
* Parser class for DER SETs. * @deprecated Use DLSetParser instead
*/ */
public class DERSetParser public class DERSetParser
implements ASN1SetParser implements ASN1SetParser
@ -36,7 +36,7 @@ public class DERSetParser
public ASN1Primitive getLoadedObject() public ASN1Primitive getLoadedObject()
throws IOException throws IOException
{ {
return new DERSet(_parser.readVector(), false); return new DLSet(_parser.readVector());
} }
/** /**

6
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERT61String.java

@ -117,11 +117,9 @@ public class DERT61String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.T61_STRING, string); out.writeEncoded(withTag, BERTags.T61_STRING, string);
} }
/** /**

6
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERT61UTF8String.java

@ -120,11 +120,9 @@ public class DERT61UTF8String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.T61_STRING, string); out.writeEncoded(withTag, BERTags.T61_STRING, string);
} }
/** /**

68
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERTaggedObject.java

@ -10,8 +10,6 @@ import java.io.IOException;
public class DERTaggedObject public class DERTaggedObject
extends ASN1TaggedObject extends ASN1TaggedObject
{ {
private static final byte[] ZERO_BYTES = new byte[0];
/** /**
* @param explicit true if an explicitly tagged object. * @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object. * @param tagNo the tag number for this object.
@ -32,29 +30,11 @@ public class DERTaggedObject
boolean isConstructed() boolean isConstructed()
{ {
if (!empty) return explicit || obj.toASN1Primitive().toDERObject().isConstructed();
{
if (explicit)
{
return true;
}
else
{
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
return primitive.isConstructed();
}
}
else
{
return true;
}
} }
int encodedLength() int encodedLength()
throws IOException throws IOException
{
if (!empty)
{ {
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
int length = primitive.encodedLength(); int length = primitive.encodedLength();
@ -71,48 +51,34 @@ public class DERTaggedObject
return StreamUtil.calculateTagLength(tagNo) + length; return StreamUtil.calculateTagLength(tagNo) + length;
} }
} }
else
{
return StreamUtil.calculateTagLength(tagNo) + 1;
}
}
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{
if (!empty)
{ {
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject(); ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
int flags = BERTags.TAGGED;
if (explicit || primitive.isConstructed())
{
flags |= BERTags.CONSTRUCTED;
}
out.writeTag(withTag, flags, tagNo);
if (explicit) if (explicit)
{ {
out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
out.writeLength(primitive.encodedLength()); out.writeLength(primitive.encodedLength());
out.writeObject(primitive);
} }
else
{ primitive.encode(out.getDERSubStream(), explicit);
//
// need to mark constructed types...
//
int flags;
if (primitive.isConstructed())
{
flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
} }
else
ASN1Primitive toDERObject()
{ {
flags = BERTags.TAGGED; return this;
} }
out.writeTag(flags, tagNo); ASN1Primitive toDLObject()
out.writeImplicitObject(primitive);
}
}
else
{ {
out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES); return this;
}
} }
} }

5
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERUTF8String.java

@ -129,9 +129,8 @@ public class DERUTF8String
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode(ASN1OutputStream out) void encode(ASN1OutputStream out, boolean withTag) throws IOException
throws IOException
{ {
out.writeEncoded(BERTags.UTF8_STRING, string); out.writeEncoded(withTag, BERTags.UTF8_STRING, string);
} }
} }

16
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERUniversalString.java

@ -1,6 +1,5 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import com.fr.third.org.bouncycastle.util.Arrays; import com.fr.third.org.bouncycastle.util.Arrays;
@ -68,7 +67,7 @@ public class DERUniversalString
} }
else else
{ {
return new DERUniversalString(((ASN1OctetString)o).getOctets()); return new DERUniversalString(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -86,20 +85,17 @@ public class DERUniversalString
public String getString() public String getString()
{ {
StringBuffer buf = new StringBuffer("#"); StringBuffer buf = new StringBuffer("#");
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ASN1OutputStream aOut = new ASN1OutputStream(bOut);
byte[] string;
try try
{ {
aOut.writeObject(this); string = getEncoded();
} }
catch (IOException e) catch (IOException e)
{ {
throw new ASN1ParsingException("internal error encoding UniversalString"); throw new ASN1ParsingException("internal error encoding UniversalString");
} }
byte[] string = bOut.toByteArray();
for (int i = 0; i != string.length; i++) for (int i = 0; i != string.length; i++)
{ {
buf.append(table[(string[i] >>> 4) & 0xf]); buf.append(table[(string[i] >>> 4) & 0xf]);
@ -129,11 +125,9 @@ public class DERUniversalString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets()); out.writeEncoded(withTag, BERTags.UNIVERSAL_STRING, string);
} }
boolean asn1Equals( boolean asn1Equals(

8
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERVideotexString.java

@ -63,7 +63,7 @@ public class DERVideotexString
} }
else else
{ {
return new DERVideotexString(((ASN1OctetString)o).getOctets()); return new DERVideotexString(ASN1OctetString.getInstance(o).getOctets());
} }
} }
@ -92,11 +92,9 @@ public class DERVideotexString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.VIDEOTEX_STRING, string); out.writeEncoded(withTag, BERTags.VIDEOTEX_STRING, string);
} }
public int hashCode() public int hashCode()

6
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DERVisibleString.java

@ -118,11 +118,9 @@ public class DERVisibleString
return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
out.writeEncoded(BERTags.VISIBLE_STRING, this.string); out.writeEncoded(withTag, BERTags.VISIBLE_STRING, this.string);
} }
boolean asn1Equals( boolean asn1Equals(

124
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLApplicationSpecific.java

@ -0,0 +1,124 @@
package com.fr.third.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* A DER encoding version of an application specific object.
*/
public class DLApplicationSpecific
extends ASN1ApplicationSpecific
{
DLApplicationSpecific(
boolean isConstructed,
int tag,
byte[] octets)
{
super(isConstructed, tag, octets);
}
/**
* Create an application specific object from the passed in data. This will assume
* the data does not represent a constructed object.
*
* @param tag the tag number for this object.
* @param octets the encoding of the object's body.
*/
public DLApplicationSpecific(
int tag,
byte[] octets)
{
this(false, tag, octets);
}
/**
* Create an application specific object with a tagging of explicit/constructed.
*
* @param tag the tag number for this object.
* @param object the object to be contained.
*/
public DLApplicationSpecific(
int tag,
ASN1Encodable object)
throws IOException
{
this(true, tag, object);
}
/**
* Create an application specific object with the tagging style given by the value of constructed.
*
* @param constructed true if the object is constructed.
* @param tag the tag number for this object.
* @param object the object to be contained.
*/
public DLApplicationSpecific(
boolean constructed,
int tag,
ASN1Encodable object)
throws IOException
{
super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
}
private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
throws IOException
{
byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DL);
if (explicit)
{
return data;
}
else
{
int lenBytes = getLengthOfHeader(data);
byte[] tmp = new byte[data.length - lenBytes];
System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
return tmp;
}
}
/**
* Create an application specific object which is marked as constructed
*
* @param tagNo the tag number for this object.
* @param vec the objects making up the application specific object.
*/
public DLApplicationSpecific(int tagNo, ASN1EncodableVector vec)
{
super(true, tagNo, getEncodedVector(vec));
}
private static byte[] getEncodedVector(ASN1EncodableVector vec)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
for (int i = 0; i != vec.size(); i++)
{
try
{
bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DL));
}
catch (IOException e)
{
throw new ASN1ParsingException("malformed object: " + e, e);
}
}
return bOut.toByteArray();
}
/* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream)
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
int flags = BERTags.APPLICATION;
if (isConstructed)
{
flags |= BERTags.CONSTRUCTED;
}
out.writeEncoded(withTag, flags, tag, octets);
}
}

32
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLBitString.java

@ -63,24 +63,13 @@ public class DLBitString
} }
else else
{ {
return fromOctetString(((ASN1OctetString)o).getOctets()); return fromOctetString(ASN1OctetString.getInstance(o).getOctets());
} }
} }
protected DLBitString( protected DLBitString(byte data, int padBits)
byte data,
int padBits)
{
this(toByteArray(data), padBits);
}
private static byte[] toByteArray(byte data)
{ {
byte[] rv = new byte[1]; super(data, padBits);
rv[0] = data;
return rv;
} }
/** /**
@ -123,17 +112,14 @@ public class DLBitString
return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1; return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
} }
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{ {
byte[] string = data; out.writeEncoded(withTag, BERTags.BIT_STRING, (byte)padBits, data);
byte[] bytes = new byte[string.length + 1]; }
bytes[0] = (byte)getPadBits();
System.arraycopy(string, 0, bytes, 1, bytes.length - 1);
out.writeEncoded(BERTags.BIT_STRING, bytes); ASN1Primitive toDLObject()
{
return this;
} }
static DLBitString fromOctetString(byte[] bytes) static DLBitString fromOctetString(byte[] bytes)

90
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLExternal.java

@ -0,0 +1,90 @@
package com.fr.third.org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* Class representing the Definite-Length-type External
*/
public class DLExternal
extends ASN1External
{
/**
* Construct a Definite-Length EXTERNAL object, the input encoding vector must have exactly two elements on it.
* <p>
* Acceptable input formats are:
* <ul>
* <li> {@link ASN1ObjectIdentifier} + data {@link DERTaggedObject} (direct reference form)</li>
* <li> {@link ASN1Integer} + data {@link DERTaggedObject} (indirect reference form)</li>
* <li> Anything but {@link DERTaggedObject} + data {@link DERTaggedObject} (data value form)</li>
* </ul>
*
* @throws IllegalArgumentException if input size is wrong, or
*/
public DLExternal(ASN1EncodableVector vector)
{
super(vector);
}
/**
* Creates a new instance of DERExternal
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param externalData The external data in its encoded form.
*/
public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, DERTaggedObject externalData)
{
this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.toASN1Primitive());
}
/**
* Creates a new instance of Definite-Length External.
* See X.690 for more informations about the meaning of these parameters
* @param directReference The direct reference or <code>null</code> if not set.
* @param indirectReference The indirect reference or <code>null</code> if not set.
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
* @param encoding The encoding to be used for the external data
* @param externalData The external data
*/
public DLExternal(ASN1ObjectIdentifier directReference, ASN1Integer indirectReference, ASN1Primitive dataValueDescriptor, int encoding, ASN1Primitive externalData)
{
super(directReference, indirectReference, dataValueDescriptor, encoding, externalData);
}
ASN1Primitive toDLObject()
{
return this;
}
int encodedLength()
throws IOException
{
return this.getEncoded().length;
}
/* (non-Javadoc)
* @see com.fr.third.org.bouncycastle.asn1.ASN1Primitive#encode(com.fr.third.org.bouncycastle.asn1.DEROutputStream)
*/
void encode(ASN1OutputStream out, boolean withTag) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (directReference != null)
{
baos.write(directReference.getEncoded(ASN1Encoding.DL));
}
if (indirectReference != null)
{
baos.write(indirectReference.getEncoded(ASN1Encoding.DL));
}
if (dataValueDescriptor != null)
{
baos.write(dataValueDescriptor.getEncoded(ASN1Encoding.DL));
}
DERTaggedObject obj = new DERTaggedObject(true, encoding, externalContent);
baos.write(obj.getEncoded(ASN1Encoding.DL));
out.writeEncoded(withTag, BERTags.CONSTRUCTED, BERTags.EXTERNAL, baos.toByteArray());
}
}

27
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLFactory.java

@ -0,0 +1,27 @@
package com.fr.third.org.bouncycastle.asn1;
class DLFactory
{
static final ASN1Sequence EMPTY_SEQUENCE = new DLSequence();
static final ASN1Set EMPTY_SET = new DLSet();
static ASN1Sequence createSequence(ASN1EncodableVector v)
{
if (v.size() < 1)
{
return EMPTY_SEQUENCE;
}
return new DLSequence(v);
}
static ASN1Set createSet(ASN1EncodableVector v)
{
if (v.size() < 1)
{
return EMPTY_SET;
}
return new DLSet(v);
}
}

23
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLOutputStream.java

@ -5,27 +5,28 @@ import java.io.OutputStream;
/** /**
* Stream that outputs encoding based on definite length. * Stream that outputs encoding based on definite length.
*
* @deprecated Will be removed from public API.
*/ */
public class DLOutputStream public class DLOutputStream
extends ASN1OutputStream extends ASN1OutputStream
{ {
public DLOutputStream( /**
OutputStream os) * @deprecated Use {@link ASN1OutputStream#create(OutputStream, String)} with
* {@link ASN1Encoding#DL} instead.
*/
public DLOutputStream(OutputStream os)
{ {
super(os); super(os);
} }
public void writeObject( void writePrimitive(ASN1Primitive primitive, boolean withTag) throws IOException
ASN1Encodable obj)
throws IOException
{
if (obj != null)
{ {
obj.toASN1Primitive().toDLObject().encode(this); primitive.toDLObject().encode(this, withTag);
} }
else
ASN1OutputStream getDLSubStream()
{ {
throw new IOException("null object detected"); return this;
}
} }
} }

93
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSequence.java

@ -1,7 +1,6 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration;
/** /**
* The DLSequence encodes a SEQUENCE using definite length form. * The DLSequence encodes a SEQUENCE using definite length form.
@ -20,56 +19,56 @@ public class DLSequence
/** /**
* create a sequence containing one object * create a sequence containing one object
* @param obj the object to go in the sequence. * @param element the object to go in the sequence.
*/ */
public DLSequence( public DLSequence(ASN1Encodable element)
ASN1Encodable obj)
{ {
super(obj); super(element);
} }
/** /**
* create a sequence containing a vector of objects. * create a sequence containing a vector of objects.
* @param v the vector of objects to make up the sequence. * @param elementVector the vector of objects to make up the sequence.
*/ */
public DLSequence( public DLSequence(ASN1EncodableVector elementVector)
ASN1EncodableVector v)
{ {
super(v); super(elementVector);
} }
/** /**
* create a sequence containing an array of objects. * create a sequence containing an array of objects.
* @param array the array of objects to make up the sequence. * @param elements the array of objects to make up the sequence.
*/ */
public DLSequence( public DLSequence(ASN1Encodable[] elements)
ASN1Encodable[] array)
{ {
super(array); super(elements);
} }
private int getBodyLength() DLSequence(ASN1Encodable[] elements, boolean clone)
throws IOException {
super(elements, clone);
}
private int getBodyLength() throws IOException
{ {
if (bodyLength < 0) if (bodyLength < 0)
{ {
int length = 0; int count = elements.length;
int totalLength = 0;
for (Enumeration e = this.getObjects(); e.hasMoreElements();) for (int i = 0; i < count; ++i)
{ {
Object obj = e.nextElement(); ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
totalLength += dlObject.encodedLength();
length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
} }
bodyLength = length; this.bodyLength = totalLength;
} }
return bodyLength; return bodyLength;
} }
int encodedLength() int encodedLength() throws IOException
throws IOException
{ {
int length = getBodyLength(); int length = getBodyLength();
@ -84,21 +83,49 @@ public class DLSequence
* ASN.1 descriptions given. Rather than just outputting SEQUENCE, * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
* we also have to specify CONSTRUCTED, and the objects length. * we also have to specify CONSTRUCTED, and the objects length.
*/ */
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out) {
throws IOException if (withTag)
{ {
ASN1OutputStream dOut = out.getDLSubStream();
int length = getBodyLength();
out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED); out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
out.writeLength(length); }
ASN1OutputStream dlOut = out.getDLSubStream();
for (Enumeration e = this.getObjects(); e.hasMoreElements();) int count = elements.length;
if (bodyLength >= 0 || count > 16)
{ {
Object obj = e.nextElement(); out.writeLength(getBodyLength());
dOut.writeObject((ASN1Encodable)obj); for (int i = 0; i < count; ++i)
{
dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
}
} }
else
{
int totalLength = 0;
ASN1Primitive[] dlObjects = new ASN1Primitive[count];
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
totalLength += dlObject.encodedLength();
}
this.bodyLength = totalLength;
out.writeLength(totalLength);
for (int i = 0; i < count; ++i)
{
dlOut.writePrimitive(dlObjects[i], true);
}
}
}
ASN1Primitive toDLObject()
{
return this;
} }
} }

12
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSequenceParser.java

@ -0,0 +1,12 @@
package com.fr.third.org.bouncycastle.asn1;
/**
* Parser class for DL SEQUENCEs.
*/
public class DLSequenceParser extends DERSequenceParser
{
DLSequenceParser(ASN1StreamParser parser)
{
super(parser);
}
}

91
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSet.java

@ -1,7 +1,6 @@
package com.fr.third.org.bouncycastle.asn1; package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration;
/** /**
* The DLSet encodes ASN.1 SET value without element ordering, * The DLSet encodes ASN.1 SET value without element ordering,
@ -64,54 +63,54 @@ public class DLSet
} }
/** /**
* @param obj - a single object that makes up the set. * @param element - a single object that makes up the set.
*/ */
public DLSet( public DLSet(ASN1Encodable element)
ASN1Encodable obj)
{ {
super(obj); super(element);
} }
/** /**
* @param v - a vector of objects making up the set. * @param elementVector - a vector of objects making up the set.
*/ */
public DLSet( public DLSet(ASN1EncodableVector elementVector)
ASN1EncodableVector v)
{ {
super(v, false); super(elementVector, false);
} }
/** /**
* create a set from an array of objects. * create a set from an array of objects.
*/ */
public DLSet( public DLSet(ASN1Encodable[] elements)
ASN1Encodable[] a)
{ {
super(a, false); super(elements, false);
} }
private int getBodyLength() DLSet(boolean isSorted, ASN1Encodable[] elements)
throws IOException {
super(isSorted, elements);
}
private int getBodyLength() throws IOException
{ {
if (bodyLength < 0) if (bodyLength < 0)
{ {
int length = 0; int count = elements.length;
int totalLength = 0;
for (Enumeration e = this.getObjects(); e.hasMoreElements();) for (int i = 0; i < count; ++i)
{ {
Object obj = e.nextElement(); ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
totalLength += dlObject.encodedLength();
length += ((ASN1Encodable)obj).toASN1Primitive().toDLObject().encodedLength();
} }
bodyLength = length; this.bodyLength = totalLength;
} }
return bodyLength; return bodyLength;
} }
int encodedLength() int encodedLength() throws IOException
throws IOException
{ {
int length = getBodyLength(); int length = getBodyLength();
@ -126,21 +125,49 @@ public class DLSet
* ASN.1 descriptions given. Rather than just outputting SET, * ASN.1 descriptions given. Rather than just outputting SET,
* we also have to specify CONSTRUCTED, and the objects length. * we also have to specify CONSTRUCTED, and the objects length.
*/ */
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out) {
throws IOException if (withTag)
{ {
ASN1OutputStream dOut = out.getDLSubStream();
int length = getBodyLength();
out.write(BERTags.SET | BERTags.CONSTRUCTED); out.write(BERTags.SET | BERTags.CONSTRUCTED);
out.writeLength(length); }
ASN1OutputStream dlOut = out.getDLSubStream();
for (Enumeration e = this.getObjects(); e.hasMoreElements();) int count = elements.length;
if (bodyLength >= 0 || count > 16)
{ {
Object obj = e.nextElement(); out.writeLength(getBodyLength());
dOut.writeObject((ASN1Encodable)obj); for (int i = 0; i < count; ++i)
{
dlOut.writePrimitive(elements[i].toASN1Primitive(), true);
}
} }
else
{
int totalLength = 0;
ASN1Primitive[] dlObjects = new ASN1Primitive[count];
for (int i = 0; i < count; ++i)
{
ASN1Primitive dlObject = elements[i].toASN1Primitive().toDLObject();
dlObjects[i] = dlObject;
totalLength += dlObject.encodedLength();
}
this.bodyLength = totalLength;
out.writeLength(totalLength);
for (int i = 0; i < count; ++i)
{
dlOut.writePrimitive(dlObjects[i], true);
}
}
}
ASN1Primitive toDLObject()
{
return this;
} }
} }

12
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLSetParser.java

@ -0,0 +1,12 @@
package com.fr.third.org.bouncycastle.asn1;
/**
* Parser class for DL SETs.
*/
public class DLSetParser extends DERSetParser
{
DLSetParser(ASN1StreamParser parser)
{
super(parser);
}
}

67
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DLTaggedObject.java

@ -10,8 +10,6 @@ import java.io.IOException;
public class DLTaggedObject public class DLTaggedObject
extends ASN1TaggedObject extends ASN1TaggedObject
{ {
private static final byte[] ZERO_BYTES = new byte[0];
/** /**
* @param explicit true if an explicitly tagged object. * @param explicit true if an explicitly tagged object.
* @param tagNo the tag number for this object. * @param tagNo the tag number for this object.
@ -27,29 +25,11 @@ public class DLTaggedObject
boolean isConstructed() boolean isConstructed()
{ {
if (!empty) return explicit || obj.toASN1Primitive().toDLObject().isConstructed();
{
if (explicit)
{
return true;
}
else
{
ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
return primitive.isConstructed();
}
}
else
{
return true;
}
} }
int encodedLength() int encodedLength()
throws IOException throws IOException
{
if (!empty)
{ {
int length = obj.toASN1Primitive().toDLObject().encodedLength(); int length = obj.toASN1Primitive().toDLObject().encodedLength();
@ -65,48 +45,29 @@ public class DLTaggedObject
return StreamUtil.calculateTagLength(tagNo) + length; return StreamUtil.calculateTagLength(tagNo) + length;
} }
} }
else
{
return StreamUtil.calculateTagLength(tagNo) + 1;
}
}
void encode( void encode(ASN1OutputStream out, boolean withTag) throws IOException
ASN1OutputStream out)
throws IOException
{
if (!empty)
{ {
ASN1Primitive primitive = obj.toASN1Primitive().toDLObject(); ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
if (explicit) int flags = BERTags.TAGGED;
{ if (explicit || primitive.isConstructed())
out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
out.writeLength(primitive.encodedLength());
out.writeObject(primitive);
}
else
{
//
// need to mark constructed types...
//
int flags;
if (primitive.isConstructed())
{ {
flags = BERTags.CONSTRUCTED | BERTags.TAGGED; flags |= BERTags.CONSTRUCTED;
} }
else
out.writeTag(withTag, flags, tagNo);
if (explicit)
{ {
flags = BERTags.TAGGED; out.writeLength(primitive.encodedLength());
} }
out.writeTag(flags, tagNo); out.getDLSubStream().writePrimitive(primitive, explicit);
out.writeImplicitObject(primitive);
} }
}
else ASN1Primitive toDLObject()
{ {
out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES); return this;
}
} }
} }

80
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DateUtil.java

@ -0,0 +1,80 @@
package com.fr.third.org.bouncycastle.asn1;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
class DateUtil
{
private static Long ZERO = longValueOf(0);
private static final Map localeCache = new HashMap();
static Locale EN_Locale = forEN();
private static Locale forEN()
{
if ("en".equalsIgnoreCase(Locale.getDefault().getLanguage()))
{
return Locale.getDefault();
}
Locale[] locales = Locale.getAvailableLocales();
for (int i = 0; i != locales.length; i++)
{
if ("en".equalsIgnoreCase(locales[i].getLanguage()))
{
return locales[i];
}
}
return Locale.getDefault();
}
static Date epochAdjust(Date date)
throws ParseException
{
Locale locale = Locale.getDefault();
if (locale == null)
{
return date;
}
synchronized (localeCache)
{
Long adj = (Long)localeCache.get(locale);
if (adj == null)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
long v = dateF.parse("19700101000000GMT+00:00").getTime();
if (v == 0)
{
adj = ZERO;
}
else
{
adj = longValueOf(v);
}
localeCache.put(locale, adj);
}
if (adj != ZERO)
{
return new Date(date.getTime() - adj.longValue());
}
return date;
}
}
private static Long longValueOf(long v)
{
return Long.valueOf(v);
}
}

12
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/DefiniteLengthInputStream.java

@ -15,13 +15,15 @@ class DefiniteLengthInputStream
private static final byte[] EMPTY_BYTES = new byte[0]; private static final byte[] EMPTY_BYTES = new byte[0];
private final int _originalLength; private final int _originalLength;
private int _remaining; private int _remaining;
DefiniteLengthInputStream( DefiniteLengthInputStream(
InputStream in, InputStream in,
int length) int length,
int limit)
{ {
super(in, length); super(in, limit, length);
if (length < 0) if (length < 0)
{ {
@ -97,6 +99,12 @@ class DefiniteLengthInputStream
return EMPTY_BYTES; return EMPTY_BYTES;
} }
// make sure it's safe to do this!
if (_remaining >= this.getLimit())
{
throw new IOException("corrupted stream - out of bounds length found: " + _remaining + " >= " + this.getLimit());
}
byte[] bytes = new byte[_remaining]; byte[] bytes = new byte[_remaining];
if ((_remaining -= Streams.readFully(_in, bytes)) != 0) if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
{ {

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/IndefiniteLengthInputStream.java

@ -17,7 +17,7 @@ class IndefiniteLengthInputStream
int limit) int limit)
throws IOException throws IOException
{ {
super(in, limit); super(in, limit, limit);
_b1 = in.read(); _b1 = in.read();
_b2 = in.read(); _b2 = in.read();

109
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/LazyEncodedSequence.java

@ -2,6 +2,7 @@ package com.fr.third.org.bouncycastle.asn1;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Iterator;
/** /**
* Note: this class is for processing DER/DL encoded sequences only. * Note: this class is for processing DER/DL encoded sequences only.
@ -11,99 +12,117 @@ class LazyEncodedSequence
{ {
private byte[] encoded; private byte[] encoded;
LazyEncodedSequence( LazyEncodedSequence(byte[] encoded) throws IOException
byte[] encoded)
throws IOException
{ {
// NOTE: Initially, the actual 'elements' will be empty
super();
this.encoded = encoded; this.encoded = encoded;
} }
private void parse() public synchronized ASN1Encodable getObjectAt(int index)
{ {
Enumeration en = new LazyConstructionEnumeration(encoded); force();
while (en.hasMoreElements()) return super.getObjectAt(index);
{
seq.addElement(en.nextElement());
}
encoded = null;
} }
public synchronized ASN1Encodable getObjectAt(int index) public synchronized Enumeration getObjects()
{ {
if (encoded != null) if (null != encoded)
{ {
parse(); return new LazyConstructionEnumeration(encoded);
} }
return super.getObjectAt(index); return super.getObjects();
} }
public synchronized Enumeration getObjects() public synchronized int hashCode()
{ {
if (encoded == null) force();
{
return super.getObjects(); return super.hashCode();
} }
return new LazyConstructionEnumeration(encoded); public synchronized Iterator<ASN1Encodable> iterator()
{
force();
return super.iterator();
} }
public synchronized int size() public synchronized int size()
{ {
if (encoded != null) force();
{
parse();
}
return super.size(); return super.size();
} }
ASN1Primitive toDERObject() public synchronized ASN1Encodable[] toArray()
{ {
if (encoded != null) force();
{
parse(); return super.toArray();
} }
return super.toDERObject(); ASN1Encodable[] toArrayInternal()
{
force();
return super.toArrayInternal();
} }
ASN1Primitive toDLObject() synchronized int encodedLength()
throws IOException
{ {
if (encoded != null) if (null != encoded)
{ {
parse(); return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length;
} }
return super.toDLObject(); return super.toDLObject().encodedLength();
} }
int encodedLength() synchronized void encode(ASN1OutputStream out, boolean withTag) throws IOException
throws IOException
{ {
if (encoded != null) if (null != encoded)
{ {
return 1 + StreamUtil.calculateBodyLength(encoded.length) + encoded.length; out.writeEncoded(withTag, BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded);
} }
else else
{ {
return super.toDLObject().encodedLength(); super.toDLObject().encode(out, withTag);
} }
} }
void encode( synchronized ASN1Primitive toDERObject()
ASN1OutputStream out)
throws IOException
{ {
if (encoded != null) force();
return super.toDERObject();
}
synchronized ASN1Primitive toDLObject()
{ {
out.writeEncoded(BERTags.SEQUENCE | BERTags.CONSTRUCTED, encoded); force();
return super.toDLObject();
} }
else
private void force()
{
if (null != encoded)
{ {
super.toDLObject().encode(out); ASN1EncodableVector v = new ASN1EncodableVector();
Enumeration en = new LazyConstructionEnumeration(encoded);
while (en.hasMoreElements())
{
v.add((ASN1Primitive)en.nextElement());
}
this.elements = v.takeElements();
this.encoded = null;
} }
} }
} }

12
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/LimitedInputStream.java

@ -10,19 +10,27 @@ abstract class LimitedInputStream
{ {
protected final InputStream _in; protected final InputStream _in;
private int _limit; private int _limit;
private int _length;
LimitedInputStream( LimitedInputStream(
InputStream in, InputStream in,
int limit) int limit,
int length)
{ {
this._in = in; this._in = in;
this._limit = limit; this._limit = limit;
this._length = length;
}
int getLimit()
{
return _limit;
} }
int getRemaining() int getRemaining()
{ {
// TODO: maybe one day this can become more accurate // TODO: maybe one day this can become more accurate
return _limit; return _length;
} }
protected void setParentEofDetect(boolean on) protected void setParentEofDetect(boolean on)

4
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/StreamUtil.java

@ -11,7 +11,7 @@ class StreamUtil
private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory(); private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
/** /**
* Find out possible longest length... * Find out possible longest length, capped by available memory.
* *
* @param in input stream of interest * @param in input stream of interest
* @return length calculation or MAX_VALUE. * @return length calculation or MAX_VALUE.
@ -20,7 +20,7 @@ class StreamUtil
{ {
if (in instanceof LimitedInputStream) if (in instanceof LimitedInputStream)
{ {
return ((LimitedInputStream)in).getRemaining(); return ((LimitedInputStream)in).getLimit();
} }
else if (in instanceof ASN1InputStream) else if (in instanceof ASN1InputStream)
{ {

18
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/anssi/ANSSINamedCurves.java

@ -9,6 +9,7 @@ import com.fr.third.org.bouncycastle.asn1.x9.X9ECParameters;
import com.fr.third.org.bouncycastle.asn1.x9.X9ECParametersHolder; import com.fr.third.org.bouncycastle.asn1.x9.X9ECParametersHolder;
import com.fr.third.org.bouncycastle.asn1.x9.X9ECPoint; import com.fr.third.org.bouncycastle.asn1.x9.X9ECPoint;
import com.fr.third.org.bouncycastle.math.ec.ECCurve; import com.fr.third.org.bouncycastle.math.ec.ECCurve;
import com.fr.third.org.bouncycastle.math.ec.WNafUtil;
import com.fr.third.org.bouncycastle.util.Strings; import com.fr.third.org.bouncycastle.util.Strings;
import com.fr.third.org.bouncycastle.util.encoders.Hex; import com.fr.third.org.bouncycastle.util.encoders.Hex;
@ -17,15 +18,21 @@ import com.fr.third.org.bouncycastle.util.encoders.Hex;
*/ */
public class ANSSINamedCurves public class ANSSINamedCurves
{ {
private static X9ECPoint configureBasepoint(ECCurve curve, String encoding)
{
X9ECPoint G = new X9ECPoint(curve, Hex.decodeStrict(encoding));
WNafUtil.configureBasepoint(G.getPoint());
return G;
}
private static ECCurve configureCurve(ECCurve curve) private static ECCurve configureCurve(ECCurve curve)
{ {
return curve; return curve;
} }
private static BigInteger fromHex( private static BigInteger fromHex(String hex)
String hex)
{ {
return new BigInteger(1, Hex.decode(hex)); return new BigInteger(1, Hex.decodeStrict(hex));
} }
/* /*
@ -43,9 +50,8 @@ public class ANSSINamedCurves
BigInteger h = BigInteger.valueOf(1); BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h)); ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
X9ECPoint G = new X9ECPoint(curve, Hex.decode("04" X9ECPoint G = configureBasepoint(curve,
+ "B6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF" "04B6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB");
+ "6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB"));
return new X9ECParameters(curve, G, n, h, S); return new X9ECParameters(curve, G, n, h, S);
} }

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/anssi/ANSSIObjectIdentifiers.java

@ -7,5 +7,5 @@ import com.fr.third.org.bouncycastle.asn1.ASN1ObjectIdentifier;
*/ */
public interface ANSSIObjectIdentifiers public interface ANSSIObjectIdentifiers
{ {
static final ASN1ObjectIdentifier FRP256v1 = new ASN1ObjectIdentifier("1.2.250.1.223.101.256.1"); ASN1ObjectIdentifier FRP256v1 = new ASN1ObjectIdentifier("1.2.250.1.223.101.256.1");
} }

83
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java

@ -84,19 +84,77 @@ public interface BCObjectIdentifiers
* XMSS * XMSS
*/ */
public static final ASN1ObjectIdentifier xmss = bc_sig.branch("2"); public static final ASN1ObjectIdentifier xmss = bc_sig.branch("2");
public static final ASN1ObjectIdentifier xmss_with_SHA256 = xmss.branch("1"); public static final ASN1ObjectIdentifier xmss_SHA256ph = xmss.branch("1");
public static final ASN1ObjectIdentifier xmss_with_SHA512 = xmss.branch("2"); public static final ASN1ObjectIdentifier xmss_SHA512ph = xmss.branch("2");
public static final ASN1ObjectIdentifier xmss_with_SHAKE128 = xmss.branch("3"); public static final ASN1ObjectIdentifier xmss_SHAKE128ph = xmss.branch("3");
public static final ASN1ObjectIdentifier xmss_with_SHAKE256 = xmss.branch("4"); public static final ASN1ObjectIdentifier xmss_SHAKE256ph = xmss.branch("4");
public static final ASN1ObjectIdentifier xmss_SHA256 = xmss.branch("5");
public static final ASN1ObjectIdentifier xmss_SHA512 = xmss.branch("6");
public static final ASN1ObjectIdentifier xmss_SHAKE128 = xmss.branch("7");
public static final ASN1ObjectIdentifier xmss_SHAKE256 = xmss.branch("8");
/** /**
* XMSS^MT * XMSS^MT
*/ */
public static final ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3"); public static final ASN1ObjectIdentifier xmss_mt = bc_sig.branch("3");
public static final ASN1ObjectIdentifier xmss_mt_with_SHA256 = xmss_mt.branch("1"); public static final ASN1ObjectIdentifier xmss_mt_SHA256ph = xmss_mt.branch("1");
public static final ASN1ObjectIdentifier xmss_mt_with_SHA512 = xmss_mt.branch("2"); public static final ASN1ObjectIdentifier xmss_mt_SHA512ph = xmss_mt.branch("2");
public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt.branch("3"); public static final ASN1ObjectIdentifier xmss_mt_SHAKE128ph = xmss_mt.branch("3");
public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt.branch("4"); public static final ASN1ObjectIdentifier xmss_mt_SHAKE256ph = xmss_mt.branch("4");
public static final ASN1ObjectIdentifier xmss_mt_SHA256 = xmss_mt.branch("5");
public static final ASN1ObjectIdentifier xmss_mt_SHA512 = xmss_mt.branch("6");
public static final ASN1ObjectIdentifier xmss_mt_SHAKE128 = xmss_mt.branch("7");
public static final ASN1ObjectIdentifier xmss_mt_SHAKE256 = xmss_mt.branch("8");
// old OIDs.
/**
* @deprecated use xmss_SHA256ph
*/
public static final ASN1ObjectIdentifier xmss_with_SHA256 = xmss_SHA256ph;
/**
* @deprecated use xmss_SHA512ph
*/
public static final ASN1ObjectIdentifier xmss_with_SHA512 = xmss_SHA512ph;
/**
* @deprecated use xmss_SHAKE128ph
*/
public static final ASN1ObjectIdentifier xmss_with_SHAKE128 = xmss_SHAKE128ph;
/**
* @deprecated use xmss_SHAKE256ph
*/
public static final ASN1ObjectIdentifier xmss_with_SHAKE256 = xmss_SHAKE256ph;
/**
* @deprecated use xmss_mt_SHA256ph
*/
public static final ASN1ObjectIdentifier xmss_mt_with_SHA256 = xmss_mt_SHA256ph;
/**
* @deprecated use xmss_mt_SHA512ph
*/
public static final ASN1ObjectIdentifier xmss_mt_with_SHA512 = xmss_mt_SHA512ph;
/**
* @deprecated use xmss_mt_SHAKE128ph
*/
public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE128 = xmss_mt_SHAKE128;
/**
* @deprecated use xmss_mt_SHAKE256ph
*/
public static final ASN1ObjectIdentifier xmss_mt_with_SHAKE256 = xmss_mt_SHAKE256;
/**
* qTESLA
*/
public static final ASN1ObjectIdentifier qTESLA = bc_sig.branch("4");
public static final ASN1ObjectIdentifier qTESLA_Rnd1_I = qTESLA.branch("1");
public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_size = qTESLA.branch("2");
public static final ASN1ObjectIdentifier qTESLA_Rnd1_III_speed = qTESLA.branch("3");
public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_I = qTESLA.branch("4");
public static final ASN1ObjectIdentifier qTESLA_Rnd1_p_III = qTESLA.branch("5");
public static final ASN1ObjectIdentifier qTESLA_p_I = qTESLA.branch("11");
public static final ASN1ObjectIdentifier qTESLA_p_III = qTESLA.branch("12");
/** /**
* key_exchange(3) algorithms * key_exchange(3) algorithms
@ -107,4 +165,13 @@ public interface BCObjectIdentifiers
* NewHope * NewHope
*/ */
public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1"); public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
/**
* X.509 extension(4) values
* <p>
* 1.3.6.1.4.1.22554.4
*/
public static final ASN1ObjectIdentifier bc_ext = bc.branch("4");
public static final ASN1ObjectIdentifier linkedCertificate = bc_ext.branch("1");
} }

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/EncryptedObjectStoreData.java

@ -61,7 +61,7 @@ public class EncryptedObjectStoreData
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(encryptionAlgorithm); v.add(encryptionAlgorithm);
v.add(encryptedContent); v.add(encryptedContent);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/EncryptedPrivateKeyData.java

@ -70,7 +70,7 @@ public class EncryptedPrivateKeyData
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(encryptedPrivateKeyInfo); v.add(encryptedPrivateKeyInfo);
v.add(new DERSequence(certificateChain)); v.add(new DERSequence(certificateChain));

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/EncryptedSecretKeyData.java

@ -63,7 +63,7 @@ public class EncryptedSecretKeyData
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(keyEncryptionAlgorithm); v.add(keyEncryptionAlgorithm);
v.add(encryptedKeyData); v.add(encryptedKeyData);

126
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/LinkedCertificate.java

@ -0,0 +1,126 @@
package com.fr.third.org.bouncycastle.asn1.bc;
import com.fr.third.org.bouncycastle.asn1.ASN1EncodableVector;
import com.fr.third.org.bouncycastle.asn1.ASN1Object;
import com.fr.third.org.bouncycastle.asn1.ASN1Primitive;
import com.fr.third.org.bouncycastle.asn1.ASN1Sequence;
import com.fr.third.org.bouncycastle.asn1.ASN1TaggedObject;
import com.fr.third.org.bouncycastle.asn1.DERSequence;
import com.fr.third.org.bouncycastle.asn1.DERTaggedObject;
import com.fr.third.org.bouncycastle.asn1.x500.X500Name;
import com.fr.third.org.bouncycastle.asn1.x509.DigestInfo;
import com.fr.third.org.bouncycastle.asn1.x509.GeneralName;
import com.fr.third.org.bouncycastle.asn1.x509.GeneralNames;
/**
* Extension to tie an alternate certificate to the containing certificate.
* <pre>
* LinkedCertificate := SEQUENCE {
* digest DigestInfo, -- digest of PQC certificate
* certLocation GeneralName, -- location of PQC certificate
* certIssuer [0] Name OPTIONAL, -- issuer of PQC cert (if different from current certificate)
* cACerts [1] GeneralNames OPTIONAL, -- CA certificates for PQC cert (one of more locations)
* }
* </pre>
*/
public class LinkedCertificate
extends ASN1Object
{
private final DigestInfo digest;
private final GeneralName certLocation;
private X500Name certIssuer;
private GeneralNames cACerts;
public LinkedCertificate(DigestInfo digest, GeneralName certLocation)
{
this(digest, certLocation, null, null);
}
public LinkedCertificate(DigestInfo digest, GeneralName certLocation, X500Name certIssuer, GeneralNames cACerts)
{
this.digest = digest;
this.certLocation = certLocation;
this.certIssuer = certIssuer;
this.cACerts = cACerts;
}
private LinkedCertificate(ASN1Sequence seq)
{
this.digest = DigestInfo.getInstance(seq.getObjectAt(0));
this.certLocation = GeneralName.getInstance(seq.getObjectAt(1));
if (seq.size() > 2)
{
for (int i = 2; i != seq.size(); i++)
{
ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(i));
switch (tagged.getTagNo())
{
case 0:
certIssuer = X500Name.getInstance(tagged, false);
break;
case 1:
cACerts = GeneralNames.getInstance(tagged, false);
break;
default:
throw new IllegalArgumentException("unknown tag in tagged field");
}
}
}
}
public static LinkedCertificate getInstance(Object o)
{
if (o instanceof LinkedCertificate)
{
return (LinkedCertificate)o;
}
else if (o != null)
{
return new LinkedCertificate(ASN1Sequence.getInstance(o));
}
return null;
}
public DigestInfo getDigest()
{
return digest;
}
public GeneralName getCertLocation()
{
return certLocation;
}
public X500Name getCertIssuer()
{
return certIssuer;
}
public GeneralNames getCACerts()
{
return cACerts;
}
public ASN1Primitive toASN1Primitive()
{
ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(digest);
v.add(certLocation);
if (certIssuer != null)
{
v.add(new DERTaggedObject(false, 0, certIssuer));
}
if (cACerts != null)
{
v.add(new DERTaggedObject(false, 1, cACerts));
}
return new DERSequence(v);
}
}

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectData.java

@ -105,7 +105,7 @@ public class ObjectData
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(new ASN1Integer(type)); v.add(new ASN1Integer(type));
v.add(new DERUTF8String(identifier)); v.add(new DERUTF8String(identifier));

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectStore.java

@ -96,7 +96,7 @@ public class ObjectStore
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(storeData); v.add(storeData);
v.add(integrityCheck); v.add(integrityCheck);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectStoreData.java

@ -103,7 +103,7 @@ public class ObjectStoreData
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(6);
v.add(new ASN1Integer(version)); v.add(new ASN1Integer(version));
v.add(integrityAlgorithm); v.add(integrityAlgorithm);

20
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/ObjectStoreIntegrityCheck.java

@ -7,11 +7,14 @@ import com.fr.third.org.bouncycastle.asn1.ASN1Encodable;
import com.fr.third.org.bouncycastle.asn1.ASN1Object; import com.fr.third.org.bouncycastle.asn1.ASN1Object;
import com.fr.third.org.bouncycastle.asn1.ASN1Primitive; import com.fr.third.org.bouncycastle.asn1.ASN1Primitive;
import com.fr.third.org.bouncycastle.asn1.ASN1Sequence; import com.fr.third.org.bouncycastle.asn1.ASN1Sequence;
import com.fr.third.org.bouncycastle.asn1.ASN1TaggedObject;
import com.fr.third.org.bouncycastle.asn1.DERTaggedObject;
/** /**
* <pre> * <pre>
* ObjectStoreIntegrityCheck ::= CHOICE { * ObjectStoreIntegrityCheck ::= CHOICE {
* PbeMacIntegrityCheck * PbkdMacIntegrityCheck
* [0] EXPLICIT SignatureCheck
* } * }
* </pre> * </pre>
*/ */
@ -20,6 +23,7 @@ public class ObjectStoreIntegrityCheck
implements ASN1Choice implements ASN1Choice
{ {
public static final int PBKD_MAC_CHECK = 0; public static final int PBKD_MAC_CHECK = 0;
public static final int SIG_CHECK = 1;
private final int type; private final int type;
private final ASN1Object integrityCheck; private final ASN1Object integrityCheck;
@ -29,6 +33,11 @@ public class ObjectStoreIntegrityCheck
this((ASN1Encodable)macIntegrityCheck); this((ASN1Encodable)macIntegrityCheck);
} }
public ObjectStoreIntegrityCheck(SignatureCheck signatureCheck)
{
this(new DERTaggedObject(0, signatureCheck));
}
private ObjectStoreIntegrityCheck(ASN1Encodable obj) private ObjectStoreIntegrityCheck(ASN1Encodable obj)
{ {
if (obj instanceof ASN1Sequence || obj instanceof PbkdMacIntegrityCheck) if (obj instanceof ASN1Sequence || obj instanceof PbkdMacIntegrityCheck)
@ -36,6 +45,11 @@ public class ObjectStoreIntegrityCheck
this.type = PBKD_MAC_CHECK; this.type = PBKD_MAC_CHECK;
this.integrityCheck = PbkdMacIntegrityCheck.getInstance(obj); this.integrityCheck = PbkdMacIntegrityCheck.getInstance(obj);
} }
else if (obj instanceof ASN1TaggedObject)
{
this.type = SIG_CHECK;
this.integrityCheck = SignatureCheck.getInstance(((ASN1TaggedObject)obj).getObject());
}
else else
{ {
throw new IllegalArgumentException("Unknown check object in integrity check."); throw new IllegalArgumentException("Unknown check object in integrity check.");
@ -80,6 +94,10 @@ public class ObjectStoreIntegrityCheck
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
if (integrityCheck instanceof SignatureCheck)
{
return new DERTaggedObject(0, integrityCheck);
}
return integrityCheck.toASN1Primitive(); return integrityCheck.toASN1Primitive();
} }
} }

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/PbkdMacIntegrityCheck.java

@ -72,7 +72,7 @@ public class PbkdMacIntegrityCheck
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(macAlgorithm); v.add(macAlgorithm);
v.add(pbkdAlgorithm); v.add(pbkdAlgorithm);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/SecretKeyData.java

@ -62,7 +62,7 @@ public class SecretKeyData
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(keyAlgorithm); v.add(keyAlgorithm);
v.add(keyBytes); v.add(keyBytes);

117
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bc/SignatureCheck.java

@ -0,0 +1,117 @@
package com.fr.third.org.bouncycastle.asn1.bc;
import com.fr.third.org.bouncycastle.asn1.ASN1BitString;
import com.fr.third.org.bouncycastle.asn1.ASN1EncodableVector;
import com.fr.third.org.bouncycastle.asn1.ASN1Object;
import com.fr.third.org.bouncycastle.asn1.ASN1Primitive;
import com.fr.third.org.bouncycastle.asn1.ASN1Sequence;
import com.fr.third.org.bouncycastle.asn1.ASN1TaggedObject;
import com.fr.third.org.bouncycastle.asn1.DERBitString;
import com.fr.third.org.bouncycastle.asn1.DERSequence;
import com.fr.third.org.bouncycastle.asn1.DERTaggedObject;
import com.fr.third.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.fr.third.org.bouncycastle.asn1.x509.Certificate;
import com.fr.third.org.bouncycastle.util.Arrays;
/**
* <pre>
* SignatureCheck ::= SEQUENCE {
* signatureAlgorithm AlgorithmIdentifier,
* certificates [0] EXPLICIT Certificates OPTIONAL,
* signatureValue BIT STRING
* }
*
* Certificates ::= SEQUENCE OF Certificate
* </pre>
*/
public class SignatureCheck
extends ASN1Object
{
private final AlgorithmIdentifier signatureAlgorithm;
private final ASN1Sequence certificates;
private final ASN1BitString signatureValue;
public SignatureCheck(AlgorithmIdentifier signatureAlgorithm, byte[] signature)
{
this.signatureAlgorithm = signatureAlgorithm;
this.certificates = null;
this.signatureValue = new DERBitString(Arrays.clone(signature));
}
public SignatureCheck(AlgorithmIdentifier signatureAlgorithm, Certificate[] certificates, byte[] signature)
{
this.signatureAlgorithm = signatureAlgorithm;
this.certificates = new DERSequence(certificates);
this.signatureValue = new DERBitString(Arrays.clone(signature));
}
private SignatureCheck(ASN1Sequence seq)
{
this.signatureAlgorithm = AlgorithmIdentifier.getInstance(seq.getObjectAt(0));
int index = 1;
if (seq.getObjectAt(1) instanceof ASN1TaggedObject)
{
this.certificates = ASN1Sequence.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(index++)).getObject());
}
else
{
this.certificates = null;
}
this.signatureValue = DERBitString.getInstance(seq.getObjectAt(index));
}
public static SignatureCheck getInstance(Object o)
{
if (o instanceof SignatureCheck)
{
return (SignatureCheck)o;
}
else if (o != null)
{
return new SignatureCheck(ASN1Sequence.getInstance(o));
}
return null;
}
public ASN1BitString getSignature()
{
return new DERBitString(signatureValue.getBytes(), signatureValue.getPadBits());
}
public AlgorithmIdentifier getSignatureAlgorithm()
{
return signatureAlgorithm;
}
public Certificate[] getCertificates()
{
if (certificates == null)
{
return null;
}
Certificate[] certs = new Certificate[certificates.size()];
for (int i = 0; i != certs.length; i++)
{
certs[i] = Certificate.getInstance(certificates.getObjectAt(i));
}
return certs;
}
public ASN1Primitive toASN1Primitive()
{
ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(signatureAlgorithm);
if (certificates != null)
{
v.add(new DERTaggedObject(0, certificates));
}
v.add(signatureValue);
return new DERSequence(v);
}
}

16
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/bsi/BSIObjectIdentifiers.java

@ -83,22 +83,22 @@ public interface BSIObjectIdentifiers
/** AES encryption (CBC) and authentication (CMAC) /** AES encryption (CBC) and authentication (CMAC)
* OID: 0.4.0.127.0.7.1.x */ * OID: 0.4.0.127.0.7.1.x */
//FIXME replace "1" with correct OID //TODO: replace "1" with correct OID
static final ASN1ObjectIdentifier aes_cbc_cmac = algorithm.branch("1"); //static final ASN1ObjectIdentifier aes_cbc_cmac = algorithm.branch("1");
/** AES encryption (CBC) and authentication (CMAC) with 128 bit /** AES encryption (CBC) and authentication (CMAC) with 128 bit
* OID: 0.4.0.127.0.7.1.x.y1 */ * OID: 0.4.0.127.0.7.1.x.y1 */
//FIXME replace "1" with correct OID //TODO: replace "1" with correct OID
static final ASN1ObjectIdentifier id_aes128_CBC_CMAC = aes_cbc_cmac.branch("1"); //static final ASN1ObjectIdentifier id_aes128_CBC_CMAC = aes_cbc_cmac.branch("1");
/** AES encryption (CBC) and authentication (CMAC) with 192 bit /** AES encryption (CBC) and authentication (CMAC) with 192 bit
* OID: 0.4.0.127.0.7.1.x.y2 */ * OID: 0.4.0.127.0.7.1.x.y2 */
//FIXME replace "1" with correct OID //TODO: replace "1" with correct OID
static final ASN1ObjectIdentifier id_aes192_CBC_CMAC = aes_cbc_cmac.branch("1"); //static final ASN1ObjectIdentifier id_aes192_CBC_CMAC = aes_cbc_cmac.branch("1");
/** AES encryption (CBC) and authentication (CMAC) with 256 bit /** AES encryption (CBC) and authentication (CMAC) with 256 bit
* OID: 0.4.0.127.0.7.1.x.y3 */ * OID: 0.4.0.127.0.7.1.x.y3 */
//FIXME replace "1" with correct OID //TODO: replace "1" with correct OID
static final ASN1ObjectIdentifier id_aes256_CBC_CMAC = aes_cbc_cmac.branch("1"); //static final ASN1ObjectIdentifier id_aes256_CBC_CMAC = aes_cbc_cmac.branch("1");
} }

4
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCPublicationInfo.java

@ -32,7 +32,7 @@ public class CMCPublicationInfo
{ {
this.hashAlg = hashAlg; this.hashAlg = hashAlg;
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(anchorHashes.length);
for (int i = 0; i != anchorHashes.length; i++) for (int i = 0; i != anchorHashes.length; i++)
{ {
v.add(new DEROctetString(Arrays.clone(anchorHashes[i]))); v.add(new DEROctetString(Arrays.clone(anchorHashes[i])));
@ -92,7 +92,7 @@ public class CMCPublicationInfo
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(hashAlg); v.add(hashAlg);
v.add(certHashes); v.add(certHashes);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCStatusInfo.java

@ -93,7 +93,7 @@ public class CMCStatusInfo
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(cMCStatus); v.add(cMCStatus);
v.add(bodyList); v.add(bodyList);
if (statusString != null) if (statusString != null)

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCStatusInfoV2.java

@ -131,7 +131,7 @@ public class CMCStatusInfoV2
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(cMCStatus); v.add(cMCStatus);
v.add(bodyList); v.add(bodyList);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CMCUnsignedData.java

@ -61,7 +61,7 @@ public class CMCUnsignedData
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(bodyPartPath); v.add(bodyPartPath);
v.add(identifier); v.add(identifier);

4
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/CertificationRequest.java

@ -130,7 +130,7 @@ public class CertificationRequest
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(certificationRequestInfo); v.add(certificationRequestInfo);
v.add(signatureAlgorithm); v.add(signatureAlgorithm);
@ -201,7 +201,7 @@ public class CertificationRequest
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(version); v.add(version);
v.add(subject); v.add(subject);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/DecryptedPOP.java

@ -79,7 +79,7 @@ public class DecryptedPOP
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(bodyPartID); v.add(bodyPartID);
v.add(thePOPAlgID); v.add(thePOPAlgID);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/EncryptedPOP.java

@ -103,7 +103,7 @@ public class EncryptedPOP
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(5);
v.add(request); v.add(request);
v.add(cms); v.add(cms);

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/GetCRL.java

@ -100,7 +100,7 @@ public class GetCRL
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(4);
v.add(issuerName); v.add(issuerName);
if (cRLName != null) if (cRLName != null)

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/GetCert.java

@ -67,7 +67,7 @@ public class GetCert extends ASN1Object
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(issuerName); v.add(issuerName);
v.add(new ASN1Integer(serialNumber)); v.add(new ASN1Integer(serialNumber));

2
fine-bouncycastle/src/main/java/com/fr/third/org/bouncycastle/asn1/cmc/IdentityProofV2.java

@ -77,7 +77,7 @@ public class IdentityProofV2
public ASN1Primitive toASN1Primitive() public ASN1Primitive toASN1Primitive()
{ {
ASN1EncodableVector v = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(3);
v.add(proofAlgID); v.add(proofAlgID);
v.add(macAlgId); v.add(macAlgId);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save