aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/Certificate.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/Certificate.java')
-rw-r--r--libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/Certificate.java149
1 files changed, 149 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/Certificate.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/Certificate.java
new file mode 100644
index 000000000..2af17ea1f
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/java/org/spongycastle/crypto/tls/Certificate.java
@@ -0,0 +1,149 @@
+package org.spongycastle.crypto.tls;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import org.spongycastle.asn1.ASN1Encoding;
+import org.spongycastle.asn1.ASN1Primitive;
+
+/**
+ * Parsing and encoding of a <i>Certificate</i> struct from RFC 4346.
+ * <p/>
+ * <pre>
+ * opaque ASN.1Cert<2^24-1>;
+ *
+ * struct {
+ * ASN.1Cert certificate_list<0..2^24-1>;
+ * } Certificate;
+ * </pre>
+ *
+ * @see org.spongycastle.asn1.x509.Certificate
+ */
+public class Certificate
+{
+ public static final Certificate EMPTY_CHAIN = new Certificate(
+ new org.spongycastle.asn1.x509.Certificate[0]);
+
+ protected org.spongycastle.asn1.x509.Certificate[] certificateList;
+
+ public Certificate(org.spongycastle.asn1.x509.Certificate[] certificateList)
+ {
+ if (certificateList == null)
+ {
+ throw new IllegalArgumentException("'certificateList' cannot be null");
+ }
+
+ this.certificateList = certificateList;
+ }
+
+ /**
+ * @deprecated use {@link #getCertificateList()} instead
+ */
+ public org.spongycastle.asn1.x509.Certificate[] getCerts()
+ {
+ return getCertificateList();
+ }
+
+ /**
+ * @return an array of {@link org.spongycastle.asn1.x509.Certificate} representing a certificate
+ * chain.
+ */
+ public org.spongycastle.asn1.x509.Certificate[] getCertificateList()
+ {
+ return cloneCertificateList();
+ }
+
+ public org.spongycastle.asn1.x509.Certificate getCertificateAt(int index)
+ {
+ return certificateList[index];
+ }
+
+ public int getLength()
+ {
+ return certificateList.length;
+ }
+
+ /**
+ * @return <code>true</code> if this certificate chain contains no certificates, or
+ * <code>false</code> otherwise.
+ */
+ public boolean isEmpty()
+ {
+ return certificateList.length == 0;
+ }
+
+ /**
+ * Encode this {@link Certificate} to an {@link OutputStream}.
+ *
+ * @param output the {@link OutputStream} to encode to.
+ * @throws IOException
+ */
+ public void encode(OutputStream output)
+ throws IOException
+ {
+ Vector derEncodings = new Vector(this.certificateList.length);
+
+ int totalLength = 0;
+ for (int i = 0; i < this.certificateList.length; ++i)
+ {
+ byte[] derEncoding = certificateList[i].getEncoded(ASN1Encoding.DER);
+ derEncodings.addElement(derEncoding);
+ totalLength += derEncoding.length + 3;
+ }
+
+ TlsUtils.checkUint24(totalLength);
+ TlsUtils.writeUint24(totalLength, output);
+
+ for (int i = 0; i < derEncodings.size(); ++i)
+ {
+ byte[] derEncoding = (byte[])derEncodings.elementAt(i);
+ TlsUtils.writeOpaque24(derEncoding, output);
+ }
+ }
+
+ /**
+ * Parse a {@link Certificate} from an {@link InputStream}.
+ *
+ * @param input the {@link InputStream} to parse from.
+ * @return a {@link Certificate} object.
+ * @throws IOException
+ */
+ public static Certificate parse(InputStream input)
+ throws IOException
+ {
+ int totalLength = TlsUtils.readUint24(input);
+ if (totalLength == 0)
+ {
+ return EMPTY_CHAIN;
+ }
+
+ byte[] certListData = TlsUtils.readFully(totalLength, input);
+
+ ByteArrayInputStream buf = new ByteArrayInputStream(certListData);
+
+ Vector certificate_list = new Vector();
+ while (buf.available() > 0)
+ {
+ byte[] derEncoding = TlsUtils.readOpaque24(buf);
+ ASN1Primitive asn1Cert = TlsUtils.readDERObject(derEncoding);
+ certificate_list.addElement(org.spongycastle.asn1.x509.Certificate.getInstance(asn1Cert));
+ }
+
+ org.spongycastle.asn1.x509.Certificate[] certificateList = new org.spongycastle.asn1.x509.Certificate[certificate_list.size()];
+ for (int i = 0; i < certificate_list.size(); i++)
+ {
+ certificateList[i] = (org.spongycastle.asn1.x509.Certificate)certificate_list.elementAt(i);
+ }
+ return new Certificate(certificateList);
+ }
+
+ protected org.spongycastle.asn1.x509.Certificate[] cloneCertificateList()
+ {
+ org.spongycastle.asn1.x509.Certificate[] result = new org.spongycastle.asn1.x509.Certificate[certificateList.length];
+ System.arraycopy(certificateList, 0, result, 0, result.length);
+ return result;
+ }
+}