1 module hunt.security.cert.X509Extension; 2 3 import hunt.collection.Set; 4 5 /** 6 * Interface for an X.509 extension. 7 * 8 * <p>The extensions defined for X.509 v3 9 * {@link X509Certificate Certificates} and v2 10 * {@link X509CRL CRLs} (Certificate Revocation 11 * Lists) provide methods 12 * for associating additional attributes with users or public keys, 13 * for managing the certification hierarchy, and for managing CRL 14 * distribution. The X.509 extensions format also allows communities 15 * to define private extensions to carry information unique to those 16 * communities. 17 * 18 * <p>Each extension in a certificate/CRL may be designated as 19 * critical or non-critical. A certificate/CRL-using system (an application 20 * validating a certificate/CRL) must reject the certificate/CRL if it 21 * encounters a critical extension it does not recognize. A non-critical 22 * extension may be ignored if it is not recognized. 23 * <p> 24 * The ASN.1 definition for this is: 25 * <pre> 26 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 27 * 28 * Extension ::= SEQUENCE { 29 * extnId OBJECT IDENTIFIER, 30 * critical BOOLEAN DEFAULT FALSE, 31 * extnValue OCTET STRING 32 * -- contains a DER encoding of a value 33 * -- of the type registered for use with 34 * -- the extnId object identifier value 35 * } 36 * </pre> 37 * Since not all extensions are known, the {@code getExtensionValue} 38 * method returns the DER-encoded OCTET STRING of the 39 * extension value (i.e., the {@code extnValue}). This can then 40 * be handled by a <em>Class</em> that understands the extension. 41 * 42 * @author Hemma Prafullchandra 43 */ 44 45 public interface X509Extension { 46 47 /** 48 * Check if there is a critical extension that is not supported. 49 * 50 * @return {@code true} if a critical extension is found that is 51 * not supported, otherwise {@code false}. 52 */ 53 public bool hasUnsupportedCriticalExtension(); 54 55 /** 56 * Gets a Set of the OID strings for the extension(s) marked 57 * CRITICAL in the certificate/CRL managed by the object 58 * implementing this interface. 59 * 60 * Here is sample code to get a Set of critical extensions from an 61 * X509Certificate and print the OIDs: 62 * <pre>{@code 63 * X509Certificate cert = null; 64 * try (InputStream inStrm = new FileInputStream("DER-encoded-Cert")) { 65 * CertificateFactory cf = CertificateFactory.getInstance("X.509"); 66 * cert = (X509Certificate)cf.generateCertificate(inStrm); 67 * } 68 * 69 * Set!string critSet = cert.getCriticalExtensionOIDs(); 70 * if (critSet !is null && !critSet.isEmpty()) { 71 * System.out.println("Set of critical extensions:"); 72 * for (string oid : critSet) { 73 * System.out.println(oid); 74 * } 75 * } 76 * }</pre> 77 * @return a Set (or an empty Set if none are marked critical) of 78 * the extension OID strings for extensions that are marked critical. 79 * If there are no extensions present at all, then this method returns 80 * null. 81 */ 82 public Set!string getCriticalExtensionOIDs(); 83 84 /** 85 * Gets a Set of the OID strings for the extension(s) marked 86 * NON-CRITICAL in the certificate/CRL managed by the object 87 * implementing this interface. 88 * 89 * Here is sample code to get a Set of non-critical extensions from an 90 * X509CRL revoked certificate entry and print the OIDs: 91 * <pre>{@code 92 * CertificateFactory cf = null; 93 * X509CRL crl = null; 94 * try (InputStream inStrm = new FileInputStream("DER-encoded-CRL")) { 95 * cf = CertificateFactory.getInstance("X.509"); 96 * crl = (X509CRL)cf.generateCRL(inStrm); 97 * } 98 * 99 * byte[] certData = <DER-encoded certificate data> 100 * ByteArrayInputStream bais = new ByteArrayInputStream(certData); 101 * X509Certificate cert = (X509Certificate)cf.generateCertificate(bais); 102 * X509CRLEntry badCert = 103 * crl.getRevokedCertificate(cert.getSerialNumber()); 104 * 105 * if (badCert !is null) { 106 * Set!string nonCritSet = badCert.getNonCriticalExtensionOIDs(); 107 * if (nonCritSet !is null) 108 * for (string oid : nonCritSet) { 109 * System.out.println(oid); 110 * } 111 * } 112 * }</pre> 113 * 114 * @return a Set (or an empty Set if none are marked non-critical) of 115 * the extension OID strings for extensions that are marked non-critical. 116 * If there are no extensions present at all, then this method returns 117 * null. 118 */ 119 public Set!string getNonCriticalExtensionOIDs(); 120 121 /** 122 * Gets the DER-encoded OCTET string for the extension value 123 * (<em>extnValue</em>) identified by the passed-in {@code oid} 124 * string. 125 * The {@code oid} string is 126 * represented by a set of nonnegative whole numbers separated 127 * by periods. 128 * 129 * <p>For example:<br> 130 * <table border=groove summary="Examples of OIDs and extension names"> 131 * <tr> 132 * <th>OID <em>(Object Identifier)</em></th> 133 * <th>Extension Name</th></tr> 134 * <tr><td>2.5.29.14</td> 135 * <td>SubjectKeyIdentifier</td></tr> 136 * <tr><td>2.5.29.15</td> 137 * <td>KeyUsage</td></tr> 138 * <tr><td>2.5.29.16</td> 139 * <td>PrivateKeyUsage</td></tr> 140 * <tr><td>2.5.29.17</td> 141 * <td>SubjectAlternativeName</td></tr> 142 * <tr><td>2.5.29.18</td> 143 * <td>IssuerAlternativeName</td></tr> 144 * <tr><td>2.5.29.19</td> 145 * <td>BasicConstraints</td></tr> 146 * <tr><td>2.5.29.30</td> 147 * <td>NameConstraints</td></tr> 148 * <tr><td>2.5.29.33</td> 149 * <td>PolicyMappings</td></tr> 150 * <tr><td>2.5.29.35</td> 151 * <td>AuthorityKeyIdentifier</td></tr> 152 * <tr><td>2.5.29.36</td> 153 * <td>PolicyConstraints</td></tr> 154 * </table> 155 * 156 * @param oid the Object Identifier value for the extension. 157 * @return the DER-encoded octet string of the extension value or 158 * null if it is not present. 159 */ 160 public byte[] getExtensionValue(string oid); 161 }