55use Drupal \Core \Logger \LoggerChannelInterface ;
66use Drupal \key \KeyInterface ;
77use Drupal \os2web_key \Exception \RuntimeException ;
8- use Drupal \os2web_key \Plugin \KeyProvider \ AbstractCertificateKeyProvider ;
8+ use Drupal \os2web_key \Plugin \KeyType \ CertificateKeyType ;
99use Psr \Log \LoggerAwareTrait ;
1010
1111/**
@@ -25,47 +25,73 @@ public function __construct(
2525 $ this ->setLogger ($ logger );
2626 }
2727
28+ /**
29+ * Get certificates from a key.
30+ *
31+ * @param \Drupal\key\KeyInterface $key
32+ * The key.
33+ *
34+ * @return array<string, string>
35+ * The certificates.
36+ */
37+ public function getCertificates (KeyInterface $ key ): array {
38+ $ contents = $ key ->getKeyValue ();
39+ $ type = $ key ->getKeyType ();
40+ if (!($ type instanceof CertificateKeyType)) {
41+ throw new RuntimeException (sprintf ('Invalid key type: %s ' , $ type ::class));
42+ }
43+
44+ return $ this ->parseCertificates (
45+ $ contents ,
46+ $ type ->getInputFormat (),
47+ $ type ->getPassphrase (),
48+ $ key
49+ );
50+ }
51+
2852 /**
2953 * Read a certificate.
54+ *
55+ * @return array<string, string>
56+ * The certificates.
3057 */
3158 public function parseCertificates (
3259 string $ contents ,
3360 string $ format ,
3461 ?string $ passphrase ,
35- AbstractCertificateKeyProvider $ provider ,
3662 ?KeyInterface $ key ,
3763 ): array {
3864 $ certificates = [
39- ' cert ' => NULL ,
40- ' pkey ' => NULL ,
65+ self :: CERT => NULL ,
66+ self :: PKEY => NULL ,
4167 ];
4268 switch ($ format ) {
4369 case self ::FORMAT_PFX :
4470 if (!openssl_pkcs12_read ($ contents , $ certificates , $ passphrase )) {
45- throw $ this ->createSslRuntimeException ('Error reading certificate ' , $ provider , $ key );
71+ throw $ this ->createSslRuntimeException ('Error reading certificate ' , $ key );
4672 }
4773 break ;
4874
4975 case self ::FORMAT_PEM :
5076 $ certificate = @openssl_x509_read ($ contents );
5177 if (FALSE === $ certificate ) {
52- throw $ this ->createSslRuntimeException ('Error reading certificate ' , $ provider , $ key );
78+ throw $ this ->createSslRuntimeException ('Error reading certificate ' , $ key );
5379 }
5480 if (!@openssl_x509_export ($ certificate , $ certificates ['cert ' ])) {
55- throw $ this ->createSslRuntimeException ('Error exporting x509 certificate ' , $ provider , $ key );
81+ throw $ this ->createSslRuntimeException ('Error exporting x509 certificate ' , $ key );
5682 }
5783 $ pkey = @openssl_pkey_get_private ($ contents , $ passphrase );
5884 if (FALSE === $ pkey ) {
59- throw $ this ->createSslRuntimeException ('Error reading private key ' , $ provider , $ key );
85+ throw $ this ->createSslRuntimeException ('Error reading private key ' , $ key );
6086 }
6187 if (!@openssl_pkey_export ($ pkey , $ certificates ['pkey ' ])) {
62- throw $ this ->createSslRuntimeException ('Error exporting private key ' , $ provider , $ key );
88+ throw $ this ->createSslRuntimeException ('Error exporting private key ' , $ key );
6389 }
6490 break ;
6591 }
6692
67- if (!isset ($ certificates [' cert ' ], $ certificates [' pkey ' ])) {
68- throw $ this ->createRuntimeException ("Cannot read certificate parts 'cert' and 'pkey' " , $ provider , $ key );
93+ if (!isset ($ certificates [self :: CERT ], $ certificates [self :: PKEY ])) {
94+ throw $ this ->createRuntimeException ("Cannot read certificate parts 'cert' and 'pkey' " , $ key );
6995 }
7096
7197 return $ certificates ;
@@ -74,38 +100,48 @@ public function parseCertificates(
74100 /**
75101 * Create a passwordless certificate.
76102 */
77- public function createPasswordlessCertificate (array $ certificates , string $ format , AbstractCertificateKeyProvider $ provider , ?KeyInterface $ key ): string {
78- $ cert = $ certificates [' cert ' ] ?? NULL ;
103+ public function createPasswordlessCertificate (array $ certificates , string $ format , ?KeyInterface $ key ): string {
104+ $ cert = $ certificates [self :: CERT ] ?? NULL ;
79105 if (!isset ($ cert )) {
80- throw $ this ->createRuntimeException ('Certificate part "cert" not found ' , $ provider , $ key );
106+ throw $ this ->createRuntimeException ('Certificate part "cert" not found ' , $ key );
81107 }
82108
83- $ pkey = $ certificates [' pkey ' ] ?? NULL ;
109+ $ pkey = $ certificates [self :: PKEY ] ?? NULL ;
84110 if (!isset ($ pkey )) {
85- throw $ this ->createRuntimeException ('Certificate part "pkey" not found ' , $ provider , $ key );
111+ throw $ this ->createRuntimeException ('Certificate part "pkey" not found ' , $ key );
86112 }
87113
88114 $ output = '' ;
89115 switch ($ format ) {
90116 case self ::FORMAT_PEM :
91117 $ parts = ['' , '' ];
92118 if (!@openssl_x509_export ($ cert , $ parts [0 ])) {
93- throw $ this ->createSslRuntimeException ('Cannot export certificate ' , $ provider , $ key );
119+ throw $ this ->createSslRuntimeException ('Cannot export certificate ' , $ key );
94120 }
95121 if (!@openssl_pkey_export ($ pkey , $ parts [1 ])) {
96- throw $ this ->createSslRuntimeException ('Cannot export private key ' , $ provider , $ key );
122+ throw $ this ->createSslRuntimeException ('Cannot export private key ' , $ key );
123+ }
124+ $ extracerts = $ certificates ['extracerts ' ] ?? NULL ;
125+ if (is_array ($ extracerts )) {
126+ foreach ($ extracerts as $ extracert ) {
127+ $ part = '' ;
128+ if (!@openssl_x509_export ($ extracert , $ part )) {
129+ throw $ this ->createSslRuntimeException ('Cannot export certificate ' , $ key );
130+ }
131+ // $parts[] = $part;
132+ }
97133 }
98134 $ output = implode ('' , $ parts );
99135 break ;
100136
101137 case self ::FORMAT_PFX :
102138 if (!@openssl_pkcs12_export ($ cert , $ output , $ pkey , '' )) {
103- throw $ this ->createSslRuntimeException ('Cannot export certificate ' , $ provider , $ key );
139+ throw $ this ->createSslRuntimeException ('Cannot export certificate ' , $ key );
104140 }
105141 break ;
106142
107143 default :
108- throw $ this ->createSslRuntimeException (sprintf ('Invalid format: %s ' , $ format ), $ provider , $ key );
144+ throw $ this ->createSslRuntimeException (sprintf ('Invalid format: %s ' , $ format ), $ key );
109145 }
110146
111147 return $ output ;
@@ -114,14 +150,13 @@ public function createPasswordlessCertificate(array $certificates, string $forma
114150 /**
115151 * Create a runtime exception.
116152 */
117- public function createRuntimeException (string $ message , AbstractCertificateKeyProvider $ provider , ?KeyInterface $ key , ?string $ sslError = NULL ): RuntimeException {
153+ public function createRuntimeException (string $ message , ?KeyInterface $ key , ?string $ sslError = NULL ): RuntimeException {
118154 if (NULL !== $ sslError ) {
119155 $ message .= ' ( ' . $ sslError . ') ' ;
120156 }
121157 // @fixme Error: Typed property …::$logger must not be accessed before initialization.
122158 if (isset ($ this ->logger )) {
123- $ this ->logger ->error ('@id.@key: @message ' , [
124- '@id ' => $ provider ->getPluginId (),
159+ $ this ->logger ->error ('@key: @message ' , [
125160 '@key ' => $ key ?->id(),
126161 '@message ' => $ message ,
127162 ]);
@@ -133,8 +168,8 @@ public function createRuntimeException(string $message, AbstractCertificateKeyPr
133168 /**
134169 * Create an SSL runtime exception.
135170 */
136- public function createSslRuntimeException (string $ message , AbstractCertificateKeyProvider $ provider , ?KeyInterface $ key ): RuntimeException {
137- return $ this ->createRuntimeException ($ message , $ provider , $ key , openssl_error_string () ?: NULL );
171+ public function createSslRuntimeException (string $ message , ?KeyInterface $ key ): RuntimeException {
172+ return $ this ->createRuntimeException ($ message , $ key , openssl_error_string () ?: NULL );
138173 }
139174
140175}
0 commit comments