|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2017 The Netty Project |
3 | 2 | * Copyright (c) 2020-2021 Estonian Information System Authority
|
4 | 3 | *
|
5 |
| - * The Netty Project and The Web eID Project license this file to you under the |
6 |
| - * Apache License, version 2.0 (the "License"); you may not use this file except |
7 |
| - * in compliance with the License. You may obtain a copy of the License at: |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 5 | + * of this software and associated documentation files (the "Software"), to deal |
| 6 | + * in the Software without restriction, including without limitation the rights |
| 7 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 8 | + * copies of the Software, and to permit persons to whom the Software is |
| 9 | + * furnished to do so, subject to the following conditions: |
8 | 10 | *
|
9 |
| - * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | + * The above copyright notice and this permission notice shall be included in all |
| 12 | + * copies or substantial portions of the Software. |
10 | 13 | *
|
11 |
| - * Unless required by applicable law or agreed to in writing, software |
12 |
| - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
13 |
| - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
14 |
| - * License for the specific language governing permissions and limitations under |
15 |
| - * the License. |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 17 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 19 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 20 | + * SOFTWARE. |
16 | 21 | */
|
17 | 22 |
|
18 | 23 | package org.webeid.security.validator.ocsp;
|
19 | 24 |
|
20 |
| -import org.bouncycastle.asn1.ASN1Encodable; |
21 |
| -import org.bouncycastle.asn1.ASN1ObjectIdentifier; |
22 |
| -import org.bouncycastle.asn1.ASN1Primitive; |
23 |
| -import org.bouncycastle.asn1.BERTags; |
24 |
| -import org.bouncycastle.asn1.DLSequence; |
25 |
| -import org.bouncycastle.asn1.DLTaggedObject; |
26 |
| -import org.bouncycastle.asn1.x509.Extension; |
27 |
| -import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; |
| 25 | +import org.bouncycastle.asn1.ASN1String; |
| 26 | +import org.bouncycastle.asn1.x509.AccessDescription; |
| 27 | +import org.bouncycastle.asn1.x509.AuthorityInformationAccess; |
| 28 | +import org.bouncycastle.asn1.x509.GeneralName; |
| 29 | +import org.bouncycastle.cert.X509CertificateHolder; |
28 | 30 |
|
29 | 31 | import java.io.IOException;
|
30 | 32 | import java.net.URI;
|
31 |
| -import java.nio.charset.StandardCharsets; |
| 33 | +import java.security.cert.CertificateEncodingException; |
32 | 34 | import java.security.cert.X509Certificate;
|
33 | 35 | import java.util.Objects;
|
34 | 36 |
|
35 | 37 | public final class OcspUrl {
|
36 | 38 |
|
37 | 39 | public static final URI AIA_ESTEID_2015 = URI.create("http://aia.sk.ee/esteid2015");
|
38 | 40 |
|
39 |
| - /** |
40 |
| - * The OID for OCSP responder URLs. |
41 |
| - * <p> |
42 |
| - * https://oidref.com/1.3.6.1.5.5.7.48.1 |
43 |
| - */ |
44 |
| - private static final ASN1ObjectIdentifier OCSP_RESPONDER_OID |
45 |
| - = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1").intern(); |
46 |
| - |
47 | 41 | /**
|
48 | 42 | * Returns the OCSP responder {@link URI} or {@code null} if it doesn't have one.
|
49 | 43 | */
|
50 | 44 | public static URI getOcspUri(X509Certificate certificate) {
|
51 | 45 | Objects.requireNonNull(certificate, "certificate");
|
52 |
| - final byte[] value = certificate.getExtensionValue(Extension.authorityInfoAccess.getId()); |
53 |
| - if (value == null) { |
54 |
| - return null; |
55 |
| - } |
56 |
| - |
57 |
| - final ASN1Primitive authorityInfoAccess; |
| 46 | + final X509CertificateHolder certificateHolder; |
58 | 47 | try {
|
59 |
| - authorityInfoAccess = JcaX509ExtensionUtils.parseExtensionValue(value); |
60 |
| - } catch (IOException | IllegalArgumentException e) { |
61 |
| - return null; |
62 |
| - } |
63 |
| - if (!(authorityInfoAccess instanceof DLSequence)) { |
64 |
| - return null; |
65 |
| - } |
66 |
| - |
67 |
| - final DLSequence aiaSequence = (DLSequence) authorityInfoAccess; |
68 |
| - final DLTaggedObject taggedObject = findObject(aiaSequence, OCSP_RESPONDER_OID, DLTaggedObject.class); |
69 |
| - if (taggedObject == null) { |
70 |
| - return null; |
71 |
| - } |
72 |
| - |
73 |
| - if (taggedObject.getTagNo() != BERTags.OBJECT_IDENTIFIER) { |
74 |
| - return null; |
75 |
| - } |
76 |
| - |
77 |
| - final byte[] encoded; |
78 |
| - try { |
79 |
| - encoded = taggedObject.getEncoded(); |
80 |
| - } catch (IOException e) { |
81 |
| - return null; |
82 |
| - } |
83 |
| - int length = encoded[1] & 0xFF; |
84 |
| - final String uri = new String(encoded, 2, length, StandardCharsets.UTF_8); |
85 |
| - return URI.create(uri); |
86 |
| - } |
87 |
| - |
88 |
| - private static <T> T findObject(DLSequence sequence, ASN1ObjectIdentifier oid, Class<T> type) { |
89 |
| - for (final ASN1Encodable element : sequence) { |
90 |
| - if (!(element instanceof DLSequence)) { |
91 |
| - continue; |
92 |
| - } |
93 |
| - |
94 |
| - final DLSequence subSequence = (DLSequence) element; |
95 |
| - if (subSequence.size() != 2) { |
96 |
| - continue; |
97 |
| - } |
98 |
| - |
99 |
| - final ASN1Encodable key = subSequence.getObjectAt(0); |
100 |
| - final ASN1Encodable value = subSequence.getObjectAt(1); |
101 |
| - |
102 |
| - if (key.equals(oid) && type.isInstance(value)) { |
103 |
| - return type.cast(value); |
| 48 | + certificateHolder = new X509CertificateHolder(certificate.getEncoded()); |
| 49 | + final AuthorityInformationAccess authorityInformationAccess = |
| 50 | + AuthorityInformationAccess.fromExtensions(certificateHolder.getExtensions()); |
| 51 | + for (AccessDescription accessDescription : |
| 52 | + authorityInformationAccess.getAccessDescriptions()) { |
| 53 | + if (accessDescription.getAccessMethod().equals(AccessDescription.id_ad_ocsp) && |
| 54 | + accessDescription.getAccessLocation().getTagNo() == GeneralName.uniformResourceIdentifier) { |
| 55 | + final String accessLocationUrl = ((ASN1String) accessDescription.getAccessLocation().getName()) |
| 56 | + .getString(); |
| 57 | + return URI.create(accessLocationUrl); |
| 58 | + } |
104 | 59 | }
|
| 60 | + } catch (IOException | CertificateEncodingException | IllegalArgumentException | NullPointerException e) { |
| 61 | + return null; |
105 | 62 | }
|
106 |
| - |
107 | 63 | return null;
|
108 | 64 | }
|
109 | 65 |
|
|
0 commit comments