3232final class SubjectCertificatePurposeValidator implements SubjectCertificateValidator
3333{
3434
35+ private const KEY_USAGE = 'id-ce-keyUsage ' ;
36+ private const KEY_USAGE_DIGITAL_SIGNATURE = 0 ;
37+ private const EXTENDED_KEY_USAGE = 'id-ce-extKeyUsage ' ;
3538 // oid 1.3.6.1.5.5.7.3.2
3639 private const EXTENDED_KEY_USAGE_CLIENT_AUTHENTICATION = "id-kp-clientAuth " ;
3740 private $ logger ;
@@ -51,15 +54,25 @@ public function __construct(LoggerInterface $logger = null)
5154 */
5255 public function validate (X509 $ subjectCertificate ): void
5356 {
54- $ usages = $ subjectCertificate ->getExtension (' id-ce-extKeyUsage ' );
55- if (!$ usages || empty ($ usages )) {
57+ $ keyUsage = $ subjectCertificate ->getExtension (self :: KEY_USAGE );
58+ if (!$ keyUsage || empty ($ keyUsage )) {
5659 throw new UserCertificateMissingPurposeException ();
5760 }
61+ if (!$ keyUsage [self ::KEY_USAGE_DIGITAL_SIGNATURE ]) {
62+ throw new UserCertificateWrongPurposeException ();
63+ }
64+ $ usages = $ subjectCertificate ->getExtension (self ::EXTENDED_KEY_USAGE );
65+ if (!$ usages || empty ($ usages )) {
66+ // Digital Signature extension present, but Extended Key Usage extension not present,
67+ // assume it is an authentication certificate (e.g. Luxembourg eID).
68+ return ;
69+ }
5870 // Extended usages must contain TLS Web Client Authentication
5971 if (!in_array (self ::EXTENDED_KEY_USAGE_CLIENT_AUTHENTICATION , $ usages )) {
6072 throw new UserCertificateWrongPurposeException ();
6173 }
6274
6375 $ this ->logger ?->debug("User certificate can be used for client authentication. " );
6476 }
77+
6578}
0 commit comments