Skip to content

Commit fc73548

Browse files
polishing
1 parent 4e3710e commit fc73548

File tree

10 files changed

+52
-175
lines changed

10 files changed

+52
-175
lines changed

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/RelativeDistinguishedName.kt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,7 @@ open class AttributeTypeAndValue(
106106

107107
other as AttributeTypeAndValue
108108

109-
val thisStr = (this.value as? Asn1Primitive)?.asAsn1String()?.value
110-
val otherStr = (other.value as? Asn1Primitive)?.asAsn1String()?.value
111-
val thisNormalized = thisStr?.replace("\\s+".toRegex(), "")?.lowercase()
112-
val otherNormalized = otherStr?.replace("\\s+".toRegex(), "")?.lowercase()
113-
if (thisStr != null && otherStr != null) {
114-
if (thisNormalized != otherNormalized) return false
115-
} else {
116-
if (value != other.value) return false
117-
}
118-
109+
if (value != other.value) return false
119110
if (oid != other.oid) return false
120111

121112
return true

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/DNSName.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import at.asitplus.signum.indispensable.asn1.Asn1Element
55
import at.asitplus.signum.indispensable.asn1.Asn1Encodable
66
import at.asitplus.signum.indispensable.asn1.Asn1Primitive
77
import at.asitplus.signum.indispensable.asn1.Asn1String
8+
import at.asitplus.signum.indispensable.asn1.TagClass
89
import at.asitplus.signum.indispensable.asn1.encoding.decodeToIa5String
910
import at.asitplus.signum.indispensable.asn1.runRethrowing
1011
import kotlinx.io.IOException
1112

12-
class DNSName internal constructor(
13+
data class DNSName internal constructor(
1314
val value: Asn1String.IA5,
14-
allowWildcard: Boolean = true,
15+
val allowWildcard: Boolean = true,
1516
override val type: GeneralNameOption.NameType = GeneralNameOption.NameType.DNS,
1617
) : GeneralNameOption, Asn1Encodable<Asn1Primitive> {
1718

@@ -21,7 +22,7 @@ class DNSName internal constructor(
2122

2223
companion object : Asn1Decodable<Asn1Primitive, DNSName> {
2324

24-
private val tag: Asn1Element.Tag = Asn1Element.Tag(2u, false)
25+
private val tag: Asn1Element.Tag = Asn1Element.Tag(2u, false, TagClass.CONTEXT_SPECIFIC)
2526

2627
override fun doDecode(src: Asn1Primitive): DNSName {
2728
return runRethrowing {

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/EDIPartyName.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import at.asitplus.signum.indispensable.asn1.Asn1Encodable
66
import at.asitplus.signum.indispensable.asn1.Asn1ExplicitlyTagged
77
import at.asitplus.signum.indispensable.asn1.Asn1StructuralException
88

9-
class EDIPartyName (
9+
data class EDIPartyName (
1010
val value: Asn1ExplicitlyTagged,
1111
override val type: GeneralNameOption.NameType = GeneralNameOption.NameType.OTHER
1212
): GeneralNameOption, Asn1Encodable<Asn1Element> {

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/IPAddressName.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import at.asitplus.signum.indispensable.asn1.Asn1Primitive
99
import at.asitplus.signum.indispensable.asn1.encoding.encodeToAsn1OctetStringPrimitive
1010
import kotlinx.io.IOException
1111

12-
class IPAddressName(
12+
data class IPAddressName(
1313
val address: IpAddress<*>,
1414
val networkV4: IpNetwork.V4? = null,
1515
val networkV6: IpNetwork.V6? = null,

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/OtherName.kt

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import at.asitplus.signum.indispensable.asn1.Asn1Encodable
66
import at.asitplus.signum.indispensable.asn1.Asn1ExplicitlyTagged
77
import at.asitplus.signum.indispensable.asn1.Asn1StructuralException
88

9-
class OtherName (
9+
data class OtherName (
1010
val value: Asn1ExplicitlyTagged,
1111
override val type: GeneralNameOption.NameType = GeneralNameOption.NameType.OTHER
1212
): GeneralNameOption, Asn1Encodable<Asn1Element> {
@@ -15,16 +15,9 @@ class OtherName (
1515

1616
companion object : Asn1Decodable<Asn1Element, OtherName> {
1717
override fun doDecode(src: Asn1Element): OtherName {
18-
// Should be Asn1Sequence but is decoded as Tagged
1918
if (src !is Asn1ExplicitlyTagged) throw Asn1StructuralException("Invalid otherName Alternative Name found: ${src.toDerHexString()}")
19+
if (src.children.size != 2) throw Asn1StructuralException("Invalid otherName Alternative Name found (!=2 children): ${src.toDerHexString()}")
2020

21-
src.also {
22-
if (it.children.size != 2) throw Asn1StructuralException("Invalid otherName Alternative Name found (!=2 children): ${it.toDerHexString()}")
23-
if (it.children.last().tag.tagValue != GeneralNameOption.NameType.OTHER.value) throw Asn1StructuralException(
24-
"Invalid otherName Alternative Name found (implicit tag != 0): ${it.toDerHexString()}"
25-
)
26-
// ObjectIdentifier.decodeFromAsn1ContentBytes((it.children.first() as Asn1Primitive).content)
27-
}
2821
return OtherName(src)
2922
}
3023
}

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/RFC822Name.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import at.asitplus.signum.indispensable.asn1.Asn1Element
55
import at.asitplus.signum.indispensable.asn1.Asn1Encodable
66
import at.asitplus.signum.indispensable.asn1.Asn1Primitive
77
import at.asitplus.signum.indispensable.asn1.Asn1String
8+
import at.asitplus.signum.indispensable.asn1.TagClass
89
import at.asitplus.signum.indispensable.asn1.encoding.decodeToIa5String
910

10-
class RFC822Name(
11+
data class RFC822Name(
1112
val value: Asn1String.IA5,
1213
override val type: GeneralNameOption.NameType = GeneralNameOption.NameType.RFC822
1314
) : GeneralNameOption, Asn1Encodable<Asn1Primitive> {
@@ -16,7 +17,7 @@ class RFC822Name(
1617

1718
companion object : Asn1Decodable<Asn1Primitive, RFC822Name> {
1819

19-
private val tag: Asn1Element.Tag = Asn1Element.Tag(1u, false)
20+
private val tag: Asn1Element.Tag = Asn1Element.Tag(1u, false, TagClass.CONTEXT_SPECIFIC)
2021

2122
override fun doDecode(src: Asn1Primitive): RFC822Name {
2223
return RFC822Name(src.decodeToIa5String(tag))

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/RegisteredIDName.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import at.asitplus.signum.indispensable.asn1.Asn1Encodable
55
import at.asitplus.signum.indispensable.asn1.Asn1Primitive
66
import at.asitplus.signum.indispensable.asn1.ObjectIdentifier
77

8-
class RegisteredIDName (
8+
data class RegisteredIDName (
99
val value: ObjectIdentifier,
1010
override val type: GeneralNameOption.NameType = GeneralNameOption.NameType.OID
1111
): GeneralNameOption, Asn1Encodable<Asn1Primitive> {

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/UriName.kt

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import at.asitplus.signum.indispensable.asn1.Asn1Element
55
import at.asitplus.signum.indispensable.asn1.Asn1Encodable
66
import at.asitplus.signum.indispensable.asn1.Asn1Primitive
77
import at.asitplus.signum.indispensable.asn1.Asn1String
8+
import at.asitplus.signum.indispensable.asn1.TagClass
89
import at.asitplus.signum.indispensable.asn1.encoding.decodeToIa5String
910
import at.asitplus.signum.indispensable.asn1.runRethrowing
1011
import kotlinx.io.IOException
1112

12-
class UriName(
13+
data class UriName(
1314
val host: Asn1String.IA5,
1415
val hostDNS: DNSName? = null,
1516
val hostIP: IPAddressName? = null,
@@ -21,7 +22,7 @@ class UriName(
2122

2223
companion object : Asn1Decodable<Asn1Primitive, UriName> {
2324

24-
private val tag: Asn1Element.Tag = Asn1Element.Tag(6u, false)
25+
private val tag: Asn1Element.Tag = Asn1Element.Tag(6u, false, TagClass.CONTEXT_SPECIFIC)
2526

2627
override fun doDecode(src: Asn1Primitive): UriName {
2728
return runRethrowing {
@@ -35,41 +36,48 @@ class UriName(
3536
val schemeEnd = name.indexOf(':')
3637

3738
if (schemeEnd <= 0) {
38-
val normalized = name.removePrefix(".")
39+
val host = name
3940
val hostDNS = try {
40-
DNSName(Asn1String.IA5(normalized), allowWildcard)
41+
val normalizedHost = if (host.startsWith(".")) host.substring(1) else host
42+
DNSName(Asn1String.IA5(normalizedHost), allowWildcard)
4143
} catch (e: IOException) {
4244
throw IOException("Invalid URI name constraint: $name", e)
4345
}
44-
return UriName(Asn1String.IA5(name), hostDNS, null)
45-
}
4646

47-
val afterScheme = name.substring(schemeEnd + 1)
48-
val host = extractHost(afterScheme) ?: return UriName(Asn1String.IA5(name))
47+
return UriName(Asn1String.IA5(name), hostDNS, null)
48+
} else {
4949

50-
return when {
51-
host.startsWith("[") && host.endsWith("]") -> {
52-
val ipv6 = host.drop(1).dropLast(1)
53-
val hostIP = try {
54-
IPAddressName.fromString(ipv6)
55-
} catch (_: IOException) {
56-
throw IOException("Invalid URI name: host portion is not a valid IPv6 address: $name")
50+
val afterScheme = name.substring(schemeEnd + 1)
51+
val host: String? = extractHost(afterScheme)
52+
var hostIP: IPAddressName? = null
53+
var hostDNS: DNSName? = null
54+
55+
if (host != null) {
56+
if (host.startsWith("[") && host.endsWith("]")) {
57+
val ipv6Host = host.substring(1, host.length - 1)
58+
hostIP = try {
59+
IPAddressName.fromString(ipv6Host)
60+
} catch (e: IOException) {
61+
throw IOException("Invalid URI name: host portion is not a valid IPv6 address: $name")
62+
}
63+
} else {
64+
hostDNS = try {
65+
DNSName(Asn1String.IA5(host), allowWildcard)
66+
} catch (_: IOException) {
67+
null
68+
}
69+
70+
hostIP = if (hostDNS == null) {
71+
try {
72+
IPAddressName.fromString(host)
73+
} catch (_: IOException) {
74+
throw IOException("Invalid URI name: host is not a valid DNS, IPv4, or IPv6 address: $name")
75+
}
76+
} else null
5777
}
58-
UriName(Asn1String.IA5(name), hostIP = hostIP)
5978
}
60-
else -> {
61-
val hostDNS = runCatching {
62-
DNSName(Asn1String.IA5(host), allowWildcard)
63-
}.getOrNull()
64-
65-
val hostIP = hostDNS?.let { null } ?: runCatching {
66-
IPAddressName.fromString(host)
67-
}.getOrElse {
68-
throw IOException("Invalid URI name: host is not a valid DNS, IPv4, or IPv6 address: $name")
69-
}
7079

71-
UriName(Asn1String.IA5(name), hostDNS, hostIP)
72-
}
80+
return UriName(Asn1String.IA5(name), hostDNS, hostIP)
7381
}
7482
}
7583

indispensable/src/commonMain/kotlin/at/asitplus/signum/indispensable/pki/generalNames/X400AddressName.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import at.asitplus.signum.indispensable.asn1.Asn1Encodable
66
import at.asitplus.signum.indispensable.asn1.Asn1Sequence
77
import at.asitplus.signum.indispensable.asn1.Asn1StructuralException
88

9-
class X400AddressName(
9+
data class X400AddressName(
1010
val value: Asn1Element,
1111
override val type: GeneralNameOption.NameType = GeneralNameOption.NameType.X400,
1212
) : GeneralNameOption, Asn1Encodable<Asn1Element> {

supreme/src/commonTest/kotlin/at/asitplus/signum/supreme/validate/PkiExtensionsDecodingTest.kt renamed to indispensable/src/commonTest/kotlin/GeneralNameDecodingTest.kt

Lines changed: 2 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,11 @@
1-
package at.asitplus.signum.supreme.validate
2-
3-
import at.asitplus.signum.indispensable.asn1.Asn1Exception
4-
import at.asitplus.signum.indispensable.asn1.KnownOIDs
1+
package at.asitplus.signum
52
import at.asitplus.signum.indispensable.pki.X509Certificate
63
import at.asitplus.signum.indispensable.pki.generalNames.GeneralNameOption
7-
import at.asitplus.signum.indispensable.pki.generalNames.Qualifier
8-
import at.asitplus.signum.indispensable.pki.generalNames.decodeCertificatePolicies
94
import io.kotest.assertions.throwables.shouldNotThrowAny
10-
import io.kotest.assertions.throwables.shouldThrow
115
import io.kotest.core.spec.style.FreeSpec
12-
import io.kotest.matchers.collections.shouldHaveSize
136
import io.kotest.matchers.shouldBe
14-
import io.kotest.matchers.types.shouldBeInstanceOf
15-
16-
open class PkiExtensionsDecodingTest : FreeSpec({
17-
18-
"User Notice Decoding" {
19-
val certUserNoticeQualifierPem = "-----BEGIN CERTIFICATE-----\n" +
20-
"MIID/jCCAuagAwIBAgIBKDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEf\n" +
21-
"MB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMVHJ1c3Qg\n" +
22-
"QW5jaG9yMB4XDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFowZDELMAkGA1UE\n" +
23-
"BhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExNDAyBgNVBAMT\n" +
24-
"K1VzZXIgTm90aWNlIFF1YWxpZmllciBFRSBDZXJ0aWZpY2F0ZSBUZXN0MTUwggEi\n" +
25-
"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCkS8nR/CBLM63BPIASc/HIZLUW\n" +
26-
"rQrETZeD+GSRfJD3dhns+yVXSruNS2NJIb9GJ9LWU759uH95jMGlAmFltbdAyd3a\n" +
27-
"AZPqvAYmi8ZpCbS5z/Sg527s6XPHGFVjLWKuK9CN9GUyH0f9dJ2nuQTZESbELZRT\n" +
28-
"2G9GOnaPKaNet9jlmu3ykU/av1UNoLOoJ//8hXRh3NaeI6c/3i+N2eTD26t4IpkF\n" +
29-
"+ez7xx9ULTjw3xAVBJDJK+iz0KdfZcVj65ahMEmhWZRBzn1qLhboVnK7cRzCNqWz\n" +
30-
"XF+bIVRt04TaZ42laGLqPKv3cJK7KdRYxt9gRVNXnthIP0U8RODhAKlBeAALAgMB\n" +
31-
"AAGjgdkwgdYwHwYDVR0jBBgwFoAU5H1f0VyVhggsBa6+dbZlp9ldqGYwHQYDVR0O\n" +
32-
"BBYEFI+sjau3vxyGncC/k0TJSTOkGg/HMA4GA1UdDwEB/wQEAwIE8DCBgwYDVR0g\n" +
33-
"BHwwejB4BgpghkgBZQMCATABMGowaAYIKwYBBQUHAgIwXBpacTE6ICBUaGlzIGlz\n" +
34-
"IHRoZSB1c2VyIG5vdGljZSBmcm9tIHF1YWxpZmllciAxLiAgVGhpcyBjZXJ0aWZp\n" +
35-
"Y2F0ZSBpcyBmb3IgdGVzdCBwdXJwb3NlcyBvbmx5MA0GCSqGSIb3DQEBCwUAA4IB\n" +
36-
"AQChryB49S/BVXmv59TlPzJpVgyW7PstcWfaKX7Qbf+Fg3ef50OA33+0qT3dQz+L\n" +
37-
"jU0f8PMJWfrez15/izohc/YZPY2sSiJ5zxzvPGliVqDeHqnJTUc+nWT0yeghmBHZ\n" +
38-
"NEoNVSVJvSZEesXLCmNQh9g3BVZ02jx3dRDfRFesaxtTIZt8pazRdmV70aXJlT5y\n" +
39-
"f0AiFsHzrk818uk2bTipjZcMGExgV8umbnjbk0P3UQPnhRGmGGH/GNytL1xO0br9\n" +
40-
"dtwq0BNDWMELT/Ba/LhebotG1YUCYdd430Z+BxKk7gkwhFADdkbil6yFDmgRsYSY\n" +
41-
"wnOpVqmDrMivVvLaqUozgsX6\n" +
42-
"-----END CERTIFICATE-----"
43-
44-
val cert = X509Certificate.decodeFromPem(certUserNoticeQualifierPem).getOrThrow()
45-
val policyInfo = cert.findExtension(KnownOIDs.certificatePolicies_2_5_29_32)?.decodeCertificatePolicies()?.get(0)
467

47-
policyInfo?.policyQualifiers?.shouldHaveSize(1)
48-
49-
val userNotice = policyInfo?.policyQualifiers?.first()?.qualifier.shouldBeInstanceOf<Qualifier.UserNotice>()
50-
51-
userNotice.explicitText?.value shouldBe "q1: This is the user notice from qualifier 1. This certificate is for test purposes only"
52-
}
53-
54-
"CPS Pointer Decoding" {
55-
val certCPSQualifierPem = "-----BEGIN CERTIFICATE-----\n" +
56-
"MIID7zCCAtegAwIBAgIBFTANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJVUzEf\n" +
57-
"MB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEQMA4GA1UEAxMHR29vZCBD\n" +
58-
"QTAeFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMGQxCzAJBgNVBAYTAlVT\n" +
59-
"MR8wHQYDVQQKExZUZXN0IENlcnRpZmljYXRlcyAyMDExMTQwMgYDVQQDEytDUFMg\n" +
60-
"UG9pbnRlciBRdWFsaWZpZXIgRUUgQ2VydGlmaWNhdGUgVGVzdDIwMIIBIjANBgkq\n" +
61-
"hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxhW1cwuWNSLDxdyrOixpJM40XwVpspuF\n" +
62-
"pFGa73TiwQs58B/3i6tfcGygyAAmZHYGoVKjIq5LvPbirMTnCYQ4AtPQwji0AuQN\n" +
63-
"KmCwSAAjY8WPT73mSvAEpv1C6vhWq/PYcNbHq1PHstsD+V3dXc/sLvBXAXPFEbD+\n" +
64-
"nyhBpIReB+efZ+fcLDRg34th2GezPq07Q7OsROHL+35JDqtMTPibpsNSSMETa8B/\n" +
65-
"5wW0j9PxpQqufx0sVPpSXtrcK7tn0dlhhwW6UnDfOQn1XwFqmYG/UQ7fKU/uIH1a\n" +
66-
"VQTAA7GnemZ4W0XFZwoccOOiDapNmlMfMIs4JhlkpUd1uTinDGCzPwIDAQABo4HP\n" +
67-
"MIHMMB8GA1UdIwQYMBaAFFgBhCQbvCtSlEo9pRByFFH1rzrJMB0GA1UdDgQWBBTu\n" +
68-
"QtAPWnapZlaIwYeYrcROSL3D4zAOBgNVHQ8BAf8EBAMCBPAwegYDVR0gBHMwcTBv\n" +
69-
"BgpghkgBZQMCATABMGEwXwYIKwYBBQUHAgEWU2h0dHA6Ly9jc3JjLm5pc3QuZ292\n" +
70-
"L2dyb3Vwcy9TVC9jcnlwdG9fYXBwc19pbmZyYS9jc29yL3BraV9yZWdpc3RyYXRp\n" +
71-
"b24uaHRtbCNQS0lUZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQBqPx9Nphzkn+AqwLQC\n" +
72-
"tz30JaETh2kPhqKYjS7nUwbHzXz/zxeTrbQ7fRy6UGa8c1hyUtnekKZ7Y8T/cNAv\n" +
73-
"ltT+mxWtye/58YbSBSu+RdTJmJZIXbr7ZHFDwZC6gcMwvIuOe5nGRom6Yxthmciz\n" +
74-
"rCQ7m6H0VqkwZLMc2rKPKw9t2MmkUMHgxCIyh+Fa0x7jvkbe4cUP/7+CRr9tT7m+\n" +
75-
"Lh/94RYNQ16zIN/GCZnH9s4sjQLnOiGMQ41fa9zKngazpS4fMrxXPGc+NgFjVrk6\n" +
76-
"qZ+NRavzckQPEGoIZrR+8i4GFxfjFzTD+rGUiKHb/LO+n/+GKJhc3EhyIuHulRV4\n" +
77-
"eB2G\n" +
78-
"-----END CERTIFICATE-----"
79-
80-
val cert = X509Certificate.decodeFromPem(certCPSQualifierPem).getOrThrow()
81-
val policyInfo = cert.findExtension(KnownOIDs.certificatePolicies_2_5_29_32)?.decodeCertificatePolicies()?.get(0)
82-
83-
policyInfo?.policyQualifiers?.shouldHaveSize(1)
84-
85-
val cpsUri = policyInfo?.policyQualifiers?.first()?.qualifier.shouldBeInstanceOf<Qualifier.CPSUri>()
86-
87-
cpsUri.uri.value shouldBe "http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/pki_registration.html#PKITest"
88-
}
8+
open class GeneralNameDecodingTest : FreeSpec({
899

9010
"Alternative Names Decoding" {
9111
val sanRFC822namesPem = "-----BEGIN CERTIFICATE-----\n" +
@@ -142,43 +62,6 @@ open class PkiExtensionsDecodingTest : FreeSpec({
14262

14363
cert.tbsCertificate.subjectAlternativeNames?.generalNames?.size shouldBe 6
14464

145-
val sanEmptyHostPem = "-----BEGIN CERTIFICATE-----\n" +
146-
"MIIFgzCCA2ugAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UECgwEUHlD\n" +
147-
"QTAeFw0xNTEwMTAwNDQ2MTRaFw0xNjEwMDkwNDQ2MTRaMA8xDTALBgNVBAoMBFB5\n" +
148-
"Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4CpXJ7KnM/wyy/LyK\n" +
149-
"+yO/I8G0HmZd3sUcOca8WLwIgld0FMet9vC0OIIln9PvWdYEDux1IzTEPF1KWmar\n" +
150-
"2hgE9QcQzJVbELrqzh4SMvePcT9SW22qexDkzOvlVs/XaADf3t/HdSghi/uF/RVj\n" +
151-
"boN0UyeSMFPB3myKZ9lIyFaJ9bZAjKI+Yfa6nvAE5b+bIc4zd8BkxzPToDq8XyBl\n" +
152-
"j/gqYF9B3ZBJvhuztke93YDiMUlTCOIjlx/+kwjP9T1iob6oT7DanfdYxPrEIIqW\n" +
153-
"c3vaaNNh+8p7ZkB+ipKjfYa8BdaJ6mfeUUwDrBnG2PXm/GMdQPJvFoOF5tTOZ7gd\n" +
154-
"wQbJhHtlyl2Ah8dZiy4mU2o/4buHilu8FI755Q1gVCSZWvwnECHbF1yL7ZHPJ9Y0\n" +
155-
"swhbcewR0xc/uYx/Mu//o0v/IRVQ4yQZDUe0B68+pqQtlUnZR/0pIuqfyvZt6tvb\n" +
156-
"0rQt8YPahgbRxsZ81NH++0M9mD+NYuFJda+7uhS2HwAxLN2qal1repB2914z/WiW\n" +
157-
"FHdG6sjR+Dfp3wG2Q1gIkXH6KNyOATa1kbUf4IoDKZ6T1CfEixJ3DxT0PlzDGPA1\n" +
158-
"8QdF+jWxxyIJf2K2x95WotB9RGDLhKFfB/yw+PiaO3Yj8bKurUQEk/OhHhOxFESQ\n" +
159-
"I5NNdN4vY0MfykL5BbKIjyabqwIDAQABo4HoMIHlMAkGA1UdEwQCMAAwEQYJYIZI\n" +
160-
"AYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBT\n" +
161-
"ZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFBo4SEredMJKojUHEid2GIUNvQgW\n" +
162-
"MD8GA1UdIwQ4MDaAFBo4SEredMJKojUHEid2GIUNvQgWoROkETAPMQ0wCwYDVQQK\n" +
163-
"DARQeUNBggkAybQzy/uIKyIwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG\n" +
164-
"AQUFBwMBMAsGA1UdEQQEMAKCADANBgkqhkiG9w0BAQsFAAOCAgEAjDlZFmLz7JPA\n" +
165-
"8sQCjTbHkTJsn4vD/VqZPszqXuaR/De2R8EhnJEd2uTMYOG+X9iFkyxUYl3OWzQ3\n" +
166-
"GLznmjLaobuOQ9ck3RhNDaSjcqTVFGB8EXIVrM3ioh/1YB9GPlOuaUFWJKwWQkS0\n" +
167-
"GqUp5JlmWV9ScyW7R7IgZOMTb2opaww0vlSNudqaFGjpTmSd/VNPaAIAEK3NQwZa\n" +
168-
"XtQ70CqiwBAHoDWvHfFfIiXVvkze0QPzWbKPRmK0iaGzxZ9E+0+w36r2YL0vkQzQ\n" +
169-
"9fwrfPM10Am7VdHnyExbm/gr9LkJQDb6Igz3M6Hd8Ui7w8dlaw0+jzTZ1cwXyOL8\n" +
170-
"4BjbBvuFvsx8OyCaPl+EO0Z4XPquPWV80igbGbkxGQiIFMP5TyK+7yGB+1txWnMR\n" +
171-
"8ADmuMhCRUJ5Gim5p8yrq6cZTsxfgbmNsPCWeTroyscBXZEDYEzLpUvs/SI826+Y\n" +
172-
"a607iwg4YcHl9JUN2bcTay5G0tXFyrI5iLfEeMaSiRSM1EOqyYsBI9buf3WhH+rm\n" +
173-
"mlXyXt1mXhHvZDY/kWdbiHNc7GNAhhCQIuuLHhXd3/6eyMn8iGE5a/cbjPVwcYLw\n" +
174-
"bxjb9YB6yWbrAQSG/ts89v/efqqhxnpjXtZ+gJLLmBrVq70UZj0ptNKDCvsCNlHr\n" +
175-
"cHZkH9okuLpO5zNsYPEWjg1NoF4wwxw=\n" +
176-
"-----END CERTIFICATE-----"
177-
178-
shouldThrow<Asn1Exception> { X509Certificate.decodeFromPem(sanEmptyHostPem).getOrThrow() }.apply {
179-
message shouldBe "DNSName must not be null or empty"
180-
}
181-
18265
val sanOtherName = "-----BEGIN CERTIFICATE-----\n" +
18366
"MIIC/DCCAeSgAwIBAgITBmaU4PsnM8bqyYetOWyVgmVRkzANBgkqhkiG9w0BAQUF\n" +
18467
"ADAmMQ0wCwYDVQQKDARQeUNBMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUw\n" +

0 commit comments

Comments
 (0)