1717
1818/**
1919 * <pre>
20- * DeltaCertificateDescriptor ::= SEQUENCE {
21- * serialNumber CertificateSerialNumber,
22- * signature [0] IMPLICIT AlgorithmIdentifier
23- * {SIGNATURE_ALGORITHM, {...}} OPTIONAL,
24- * issuer [1] IMPLICIT Name OPTIONAL,
25- * validity [2] IMPLICIT Validity OPTIONAL,
26- * subject [3] IMPLICIT Name OPTIONAL,
27- * subjectPublicKeyInfo SubjectPublicKeyInfo,
28- * extensions [4] IMPLICIT Extensions{CertExtensions}
29- * OPTIONAL,
30- * signatureValue BIT STRING
31- * }
32- * </pre>
20+ * DeltaCertificateDescriptor ::= SEQUENCE {
21+ * serialNumber CertificateSerialNumber,
22+ * signature [0] EXPLICIT AlgorithmIdentifier {SIGNATURE_ALGORITHM, {...}} OPTIONAL,
23+ * issuer [1] EXPLICIT Name OPTIONAL,
24+ * validity [2] EXPLICIT Validity OPTIONAL,
25+ * subject [3] EXPLICIT Name OPTIONAL,
26+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
27+ * extensions [4] EXPLICIT Extensions{CertExtensions} OPTIONAL,
28+ * signatureValue BIT STRING
29+ * }
30+ * </pre>
3331 */
3432public class DeltaCertificateDescriptor
3533 extends ASN1Object
3634{
3735 private final ASN1Integer serialNumber ;
38-
39- private AlgorithmIdentifier signature ;
40- private X500Name issuer ;
41- private ASN1Sequence validity ;
42- private X500Name subject ;
43- private SubjectPublicKeyInfo subjectPublicKeyInfo ;
44- private Extensions extensions ;
45-
36+ private final AlgorithmIdentifier signature ;
37+ private final X500Name issuer ;
38+ private final Validity validity ;
39+ private final X500Name subject ;
40+ private final SubjectPublicKeyInfo subjectPublicKeyInfo ;
41+ private final Extensions extensions ;
4642 private final ASN1BitString signatureValue ;
4743
4844 public static DeltaCertificateDescriptor getInstance (
@@ -73,10 +69,15 @@ public static DeltaCertificateDescriptor fromExtensions(Extensions extensions)
7369
7470 private DeltaCertificateDescriptor (ASN1Sequence seq )
7571 {
76- this . serialNumber = ASN1Integer .getInstance (seq .getObjectAt (0 ));
72+ ASN1Integer serialNumber = ASN1Integer .getInstance (seq .getObjectAt (0 ));
7773
7874 int idx = 1 ;
7975 ASN1Encodable next = seq .getObjectAt (idx ++);
76+
77+ AlgorithmIdentifier signature = null ;
78+ X500Name issuer = null ;
79+ Validity validity = null ;
80+ X500Name subject = null ;
8081 while (next instanceof ASN1TaggedObject )
8182 {
8283 ASN1TaggedObject tagged = ASN1TaggedObject .getInstance (next );
@@ -89,7 +90,7 @@ private DeltaCertificateDescriptor(ASN1Sequence seq)
8990 issuer = X500Name .getInstance (tagged , true ); // issuer
9091 break ;
9192 case 2 :
92- validity = ASN1Sequence .getInstance (tagged , true );
93+ validity = Validity .getInstance (tagged , true );
9394 break ;
9495 case 3 :
9596 subject = X500Name .getInstance (tagged , true ); // subject
@@ -98,9 +99,11 @@ private DeltaCertificateDescriptor(ASN1Sequence seq)
9899 next = seq .getObjectAt (idx ++);
99100 }
100101
101- subjectPublicKeyInfo = subjectPublicKeyInfo .getInstance (next );
102+ SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo .getInstance (next );
102103
103104 next = seq .getObjectAt (idx );
105+
106+ Extensions extensions = null ;
104107 while (next instanceof ASN1TaggedObject )
105108 {
106109 ASN1TaggedObject tagged = ASN1TaggedObject .getInstance (next );
@@ -113,7 +116,43 @@ private DeltaCertificateDescriptor(ASN1Sequence seq)
113116 next = seq .getObjectAt (idx ++);
114117 }
115118
116- signatureValue = ASN1BitString .getInstance (next );
119+ ASN1BitString signatureValue = ASN1BitString .getInstance (next );
120+
121+ this .serialNumber = serialNumber ;
122+ this .signature = signature ;
123+ this .issuer = issuer ;
124+ this .validity = validity ;
125+ this .subject = subject ;
126+ this .subjectPublicKeyInfo = subjectPublicKeyInfo ;
127+ this .extensions = extensions ;
128+ this .signatureValue = signatureValue ;
129+ }
130+
131+ public DeltaCertificateDescriptor (ASN1Integer serialNumber , AlgorithmIdentifier signature , X500Name issuer ,
132+ Validity validity , X500Name subject , SubjectPublicKeyInfo subjectPublicKeyInfo , Extensions extensions ,
133+ ASN1BitString signatureValue )
134+ {
135+ if (serialNumber == null )
136+ {
137+ throw new NullPointerException ("'serialNumber' cannot be null" );
138+ }
139+ if (subjectPublicKeyInfo == null )
140+ {
141+ throw new NullPointerException ("'subjectPublicKeyInfo' cannot be null" );
142+ }
143+ if (signatureValue == null )
144+ {
145+ throw new NullPointerException ("'signatureValue' cannot be null" );
146+ }
147+
148+ this .serialNumber = serialNumber ;
149+ this .signature = signature ;
150+ this .issuer = issuer ;
151+ this .validity = validity ;
152+ this .subject = subject ;
153+ this .subjectPublicKeyInfo = subjectPublicKeyInfo ;
154+ this .extensions = extensions ;
155+ this .signatureValue = signatureValue ;
117156 }
118157
119158 public ASN1Integer getSerialNumber ()
@@ -131,7 +170,13 @@ public X500Name getIssuer()
131170 return issuer ;
132171 }
133172
173+ /** @deprecated Use getValidityObject instead. */
134174 public ASN1Sequence getValidity ()
175+ {
176+ return (ASN1Sequence )validity .toASN1Primitive ();
177+ }
178+
179+ public Validity getValidityObject ()
135180 {
136181 return validity ;
137182 }
@@ -156,96 +201,83 @@ public ASN1BitString getSignatureValue()
156201 return signatureValue ;
157202 }
158203
204+ /** @deprecated Use DeltaCertificateTool#trimDeltaCertificateDescriptor instead. */
159205 public DeltaCertificateDescriptor trimTo (TBSCertificate baseTbsCertificate , Extensions tbsExtensions )
160206 {
161- AlgorithmIdentifier signature = baseTbsCertificate .signature ;
162- X500Name issuer = baseTbsCertificate .issuer ;
163- ASN1Sequence validity = new DERSequence (new ASN1Encodable []
207+ return trimDeltaCertificateDescriptor (this , baseTbsCertificate , tbsExtensions );
208+ }
209+
210+ // NB: This can replace DeltaCertificateTool#trimDeltaCertificateDescriptor once 'trimTo' is removed
211+ private static DeltaCertificateDescriptor trimDeltaCertificateDescriptor (DeltaCertificateDescriptor descriptor ,
212+ TBSCertificate tbsCertificate , Extensions tbsExtensions )
213+ {
214+ ASN1Integer serialNumber = descriptor .getSerialNumber ();
215+
216+ AlgorithmIdentifier signature = descriptor .getSignature ();
217+ if (signature != null && signature .equals (tbsCertificate .getSignature ()))
164218 {
165- baseTbsCertificate .startDate , baseTbsCertificate .endDate
166- });
167- X500Name subject = baseTbsCertificate .subject ;
168- ASN1Sequence s = ASN1Sequence .getInstance (toASN1Primitive ());
169- ASN1EncodableVector v = new ASN1EncodableVector ();
219+ signature = null ;
220+ }
170221
171- Enumeration en = s .getObjects ();
172- v .add ((ASN1Encodable )en .nextElement ());
222+ X500Name issuer = descriptor .getIssuer ();
223+ if (issuer != null && issuer .equals (tbsCertificate .getIssuer ()))
224+ {
225+ issuer = null ;
226+ }
173227
174- ASN1Encodable next = ( ASN1Encodable ) en . nextElement ();
175- while ( next instanceof ASN1TaggedObject )
228+ Validity validity = descriptor . getValidityObject ();
229+ if ( validity != null && validity . equals ( tbsCertificate . getValidity ()) )
176230 {
177- ASN1TaggedObject tagged = ASN1TaggedObject .getInstance (next );
178- switch (tagged .getTagNo ())
179- {
180- case 0 :
181- AlgorithmIdentifier sig = AlgorithmIdentifier .getInstance (tagged , true );
182- if (!sig .equals (signature ))
183- {
184- v .add (next );
185- }
186- break ;
187- case 1 :
188- X500Name iss = X500Name .getInstance (tagged , true ); // issuer
189- if (!iss .equals (issuer ))
190- {
191- v .add (next );
192- }
193- break ;
194- case 2 :
195- ASN1Sequence val = ASN1Sequence .getInstance (tagged , true );
196- if (!val .equals (validity ))
197- {
198- v .add (next );
199- }
200- break ;
201- case 3 :
202- X500Name sub = X500Name .getInstance (tagged , true ); // subject
203- if (!sub .equals (subject ))
204- {
205- v .add (next );
206- }
207- break ;
208- }
209- next = (ASN1Encodable )en .nextElement ();
231+ validity = null ;
210232 }
211233
212- v .add (next );
234+ X500Name subject = descriptor .getSubject ();
235+ if (subject != null && subject .equals (tbsCertificate .getSubject ()))
236+ {
237+ subject = null ;
238+ }
213239
214- next = (ASN1Encodable )en .nextElement ();
215- while (next instanceof ASN1TaggedObject )
240+ SubjectPublicKeyInfo subjectPublicKeyInfo = descriptor .getSubjectPublicKeyInfo ();
241+
242+ Extensions extensions = descriptor .getExtensions ();
243+ if (extensions != null )
216244 {
217- ASN1TaggedObject tagged = ASN1TaggedObject .getInstance (next );
218- switch (tagged .getTagNo ())
245+ /*
246+ * draft-bonnell-lamps-chameleon-certs-05 4.1:
247+ *
248+ * [The extensions] field MUST NOT contain any extension:
249+ * - which has the same criticality and DER-encoded value as encoded in the Base Certificate,
250+ * - whose type does not appear in the Base Certificate, or
251+ * - which is of the DCD extension type (recursive Delta Certificates are not permitted).
252+ *
253+ * [...] The ordering of extensions in [the extensions] field MUST be relative to the ordering of the
254+ * extensions as they are encoded in the Delta [recte Base] Certificate.
255+ */
256+
257+ ExtensionsGenerator generator = new ExtensionsGenerator ();
258+
259+ for (Enumeration extEn = tbsExtensions .oids (); extEn .hasMoreElements ();)
219260 {
220- case 4 :
221- Extensions deltaExts = Extensions .getInstance (tagged , true );
222- ExtensionsGenerator deltaExtGen = new ExtensionsGenerator ();
223- for (Enumeration extEn = deltaExts .oids (); extEn .hasMoreElements (); )
261+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier )extEn .nextElement ();
262+ if (Extension .deltaCertificateDescriptor .equals (oid ))
224263 {
225- Extension deltaExt = deltaExts .getExtension ((ASN1ObjectIdentifier )extEn .nextElement ());
226- Extension primaryExt = tbsExtensions .getExtension (deltaExt .getExtnId ());
227-
228- if (primaryExt != null )
229- {
230- if (!deltaExt .equals (primaryExt ))
231- {
232- deltaExtGen .addExtension (deltaExt );
233- }
234- }
264+ continue ;
235265 }
236266
237- DeltaCertificateDescriptor trimmedDeltaCertDesc ;
238- if (! deltaExtGen . isEmpty ( ))
267+ Extension deltaExtension = extensions . getExtension ( oid ) ;
268+ if (deltaExtension != null && ! deltaExtension . equals ( tbsExtensions . getExtension ( oid ) ))
239269 {
240- v . add ( new DERTaggedObject ( true , 4 , deltaExtGen . generate ()) );
270+ generator . addExtension ( deltaExtension );
241271 }
242272 }
243- next = (ASN1Encodable )en .nextElement ();
273+
274+ extensions = generator .isEmpty () ? null : generator .generate ();
244275 }
245276
246- v . add ( next );
277+ ASN1BitString signatureValue = descriptor . getSignatureValue ( );
247278
248- return new DeltaCertificateDescriptor (new DERSequence (v ));
279+ return new DeltaCertificateDescriptor (serialNumber , signature , issuer , validity , subject ,
280+ subjectPublicKeyInfo , extensions , signatureValue );
249281 }
250282
251283 private void addOptional (ASN1EncodableVector v , int tag , boolean explicit , ASN1Object obj )
@@ -258,7 +290,7 @@ private void addOptional(ASN1EncodableVector v, int tag, boolean explicit, ASN1O
258290
259291 public ASN1Primitive toASN1Primitive ()
260292 {
261- ASN1EncodableVector v = new ASN1EncodableVector (7 );
293+ ASN1EncodableVector v = new ASN1EncodableVector (8 );
262294
263295 v .add (serialNumber );
264296 addOptional (v , 0 , true , signature );
0 commit comments