blob: c16d8b131c166750caec13731878b7844dcd438d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package org.bouncycastle.crypto.tls;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
/**
* Parsing and encoding of a <i>Certificate</i> struct from RFC 4346.
*
* <pre>
* opaque ASN.1Cert<2^24-1>;
*
* struct {
* ASN.1Cert certificate_list<0..2^24-1>;
* } Certificate;
* </pre>
*
* @see org.bouncycastle.asn1.x509.Certificate
*/
public class Certificate {
public static final Certificate EMPTY_CHAIN = new Certificate(
new org.bouncycastle.asn1.x509.Certificate[0]);
protected org.bouncycastle.asn1.x509.Certificate[] certificateList;
public Certificate(org.bouncycastle.asn1.x509.Certificate[] certificateList) {
if (certificateList == null) {
throw new IllegalArgumentException("'certificateList' cannot be null");
}
this.certificateList = certificateList;
}
/**
* @deprecated use {@link #getCertificateList()} instead
*/
public org.bouncycastle.asn1.x509.Certificate[] getCerts() {
return certificateList.clone();
}
/**
* @return an array of {@link org.bouncycastle.asn1.x509.Certificate} representing a certificate
* chain.
*/
public org.bouncycastle.asn1.x509.Certificate[] getCertificateList() {
return certificateList.clone();
}
public org.bouncycastle.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 encCerts = new Vector(this.certificateList.length);
int totalLength = 0;
for (int i = 0; i < this.certificateList.length; ++i) {
byte[] encCert = certificateList[i].getEncoded(ASN1Encoding.DER);
encCerts.addElement(encCert);
totalLength += encCert.length + 3;
}
TlsUtils.writeUint24(totalLength, output);
for (int i = 0; i < encCerts.size(); ++i) {
byte[] encCert = (byte[]) encCerts.elementAt(i);
TlsUtils.writeOpaque24(encCert, 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 {
org.bouncycastle.asn1.x509.Certificate[] certs;
int left = TlsUtils.readUint24(input);
if (left == 0) {
return EMPTY_CHAIN;
}
Vector tmp = new Vector();
while (left > 0) {
int size = TlsUtils.readUint24(input);
left -= 3 + size;
byte[] buf = TlsUtils.readFully(size, input);
ByteArrayInputStream bis = new ByteArrayInputStream(buf);
ASN1Primitive asn1 = new ASN1InputStream(bis).readObject();
TlsProtocol.assertEmpty(bis);
tmp.addElement(org.bouncycastle.asn1.x509.Certificate.getInstance(asn1));
}
certs = new org.bouncycastle.asn1.x509.Certificate[tmp.size()];
for (int i = 0; i < tmp.size(); i++) {
certs[i] = (org.bouncycastle.asn1.x509.Certificate) tmp.elementAt(i);
}
return new Certificate(certs);
}
}
|