View Javadoc
1   /*
2    * Copyright 2024 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.pkitesting;
17  
18  import org.bouncycastle.asn1.ASN1Encodable;
19  import org.bouncycastle.asn1.ASN1EncodableVector;
20  import org.bouncycastle.asn1.ASN1Integer;
21  import org.bouncycastle.asn1.ASN1ObjectIdentifier;
22  import org.bouncycastle.asn1.DERSequence;
23  import org.bouncycastle.asn1.x500.X500Name;
24  import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
25  import org.bouncycastle.asn1.x509.TBSCertList;
26  import org.bouncycastle.asn1.x509.Time;
27  
28  import java.io.IOException;
29  import java.io.UncheckedIOException;
30  import java.math.BigInteger;
31  import java.security.cert.X509Certificate;
32  import java.time.Instant;
33  import java.util.Date;
34  import java.util.Map;
35  
36  final class CertificateList {
37      private final X509Bundle issuer;
38      private final Instant thisUpdate;
39      private final Instant nextUpdate;
40      private final Iterable<Map.Entry<BigInteger, Instant>> revokedCerts;
41  
42      CertificateList(X509Bundle issuer, Instant thisUpdate, Instant nextUpdate,
43                      Iterable<Map.Entry<BigInteger, Instant>> revokedCerts) {
44          this.issuer = issuer;
45          this.thisUpdate = thisUpdate;
46          this.nextUpdate = nextUpdate;
47          this.revokedCerts = revokedCerts;
48      }
49  
50      byte[] getEncoded() {
51          ASN1EncodableVector vec = new ASN1EncodableVector();
52          X509Certificate cert = issuer.getCertificate();
53          vec.add(new ASN1Integer(1)); // Version 2
54          vec.add(new AlgorithmIdentifier(new ASN1ObjectIdentifier(cert.getSigAlgOID())));
55          vec.add(X500Name.getInstance(cert.getSubjectX500Principal().getEncoded()));
56          vec.add(new Time(Date.from(thisUpdate)));
57          if (nextUpdate != null) {
58              vec.add(new Time(Date.from(nextUpdate)));
59          }
60          ASN1EncodableVector revokedVec = new ASN1EncodableVector();
61          for (Map.Entry<BigInteger, Instant> revokedCert : revokedCerts) {
62              revokedVec.add(TBSCertList.CRLEntry.getInstance(new DERSequence(new ASN1Encodable[]{
63                      new ASN1Integer(revokedCert.getKey()),
64                      new Time(Date.from(revokedCert.getValue()))
65              })));
66          }
67          vec.add(new DERSequence(revokedVec));
68          TBSCertList list = new TBSCertList(new DERSequence(vec));
69          try {
70              return list.getEncoded("DER");
71          } catch (IOException e) {
72              throw new UncheckedIOException(e);
73          }
74      }
75  }