|
| 1 | +--TEST-- |
| 2 | +openssl_pkey_get_public(), openss_pkey_get_private(), openssl_x509_read() with RFC7512 URI |
| 3 | +--SKIPIF-- |
| 4 | +<?php |
| 5 | +if (!extension_loaded("openssl")) |
| 6 | + die("skip"); |
| 7 | +$PKCS11_MODULE_PATH="/usr/lib/softhsm/libsofthsm2.so"; |
| 8 | +exec('openssl help', $out, $code); |
| 9 | +if ($code > 0) die("skip couldn't locate openssl binary"); |
| 10 | +exec('softhsm2-util --version', $out, $code); |
| 11 | +if ($code > 0) die("skip couldn't locate softhsm2-util binary"); |
| 12 | +exec('pkcs11-tool --show-info --module ' . $PKCS11_MODULE_PATH, $out, $code); |
| 13 | +if ($code > 0) die("skip couldn't locate pkcs11-tool binary"); |
| 14 | +exec('pkcs11-dump info ' . $PKCS11_MODULE_PATH, $out, $code); |
| 15 | +if ($code > 0) die("skip couldn't locate pkcs11-dump binary"); |
| 16 | +?> |
| 17 | +--FILE-- |
| 18 | +<?php |
| 19 | + |
| 20 | +/* simple exec */ |
| 21 | +function sexec($cmd, &$stdout=null, &$stderr=null) { |
| 22 | + $proc = proc_open($cmd,[ |
| 23 | + 1 => ['pipe','w'], |
| 24 | + 2 => ['pipe','w'], |
| 25 | + ],$pipes); |
| 26 | + |
| 27 | + $stdout = stream_get_contents($pipes[1]); |
| 28 | + fclose($pipes[1]); |
| 29 | + |
| 30 | + $stderr = stream_get_contents($pipes[2]); |
| 31 | + fclose($pipes[2]); |
| 32 | + |
| 33 | + return proc_close($proc); |
| 34 | +} |
| 35 | + |
| 36 | +$PKCS11_MODULE_PATH="/usr/lib/softhsm/libsofthsm2.so"; |
| 37 | +putenv("PKCS11_MODULE_PATH=".$PKCS11_MODULE_PATH); |
| 38 | + |
| 39 | +$SOFTHSM2_CONF=tempnam(sys_get_temp_dir(), 'softhsm2'); |
| 40 | +$SOFTHSM2_TOKENDIR=sprintf("%s.dir", $SOFTHSM2_CONF); |
| 41 | +mkdir($SOFTHSM2_TOKENDIR); |
| 42 | +$PHP11_PIN=123456; |
| 43 | +$PHP11_SOPIN=12345678; |
| 44 | + |
| 45 | +file_put_contents($SOFTHSM2_CONF, sprintf( |
| 46 | + "directories.tokendir = %s".PHP_EOL. |
| 47 | + "objectstore.backend = file".PHP_EOL. |
| 48 | + "log.level = DEBUG".PHP_EOL. |
| 49 | + "slots.removable = false".PHP_EOL. |
| 50 | + "slots.mechanisms = ALL" |
| 51 | + , $SOFTHSM2_TOKENDIR)); |
| 52 | + |
| 53 | +putenv(sprintf("SOFTHSM2_CONF=%s", $SOFTHSM2_CONF)); |
| 54 | +sexec("softhsm2-util --show-slots | grep ^Slot | cut -d ' ' -f 2", $out); |
| 55 | +$INIT11_SLOT=(int)$out[0]; |
| 56 | +if ($INIT11_SLOT != 0) { |
| 57 | + echo "Error slot"; |
| 58 | + exec("softhsm2-util --show-slots", $out); |
| 59 | + var_dump($out); |
| 60 | + exit(1); |
| 61 | +} |
| 62 | + |
| 63 | +sexec(sprintf("softhsm2-util --init-token --free --slot %d --label TestVJToken --pin %s --so-pin %s", |
| 64 | + $INIT11_SLOT, $PHP11_PIN, $PHP11_SOPIN), $out); |
| 65 | + |
| 66 | +/* XXX custom slot is always the first one */ |
| 67 | +sexec(sprintf("pkcs11-dump slotlist %s 2>/dev/null | grep SoftHSM | head -1 | cut -f 1", |
| 68 | + $PKCS11_MODULE_PATH), $PHP11_SLOT); |
| 69 | +if (!is_string($PHP11_SLOT)) { |
| 70 | + echo "Cannot detect the slot".PHP_EOL; |
| 71 | + exit(1); |
| 72 | +} |
| 73 | +$PHP11_SLOT=(int)$PHP11_SLOT; |
| 74 | + |
| 75 | +/* |
| 76 | + * Most of these features can be supported natively by PHP, but |
| 77 | + * the purpose is to focus on RFC7512, so let's use the system tools. |
| 78 | + */ |
| 79 | +$PRIVKEYPEM=$SOFTHSM2_TOKENDIR . '.key.priv.pem'; |
| 80 | +$PRIVKEYDER=$SOFTHSM2_TOKENDIR . '.key.priv.der'; |
| 81 | +$PUBKEYDER=$SOFTHSM2_TOKENDIR . '.key.pub.der'; |
| 82 | +$CERTDER=$SOFTHSM2_TOKENDIR . '.cert.der'; |
| 83 | +sexec(sprintf("openssl genrsa -out %s 2048", $PRIVKEYPEM), $genkey); |
| 84 | +sexec(sprintf("openssl rsa -inform PEM -in %s -outform DER -out %s", $PRIVKEYPEM, $PRIVKEYDER), $pem2der); |
| 85 | + |
| 86 | +/* extract the public key */ |
| 87 | +sexec(sprintf("openssl rsa -in %s -outform DER -pubout -out %s", $PRIVKEYPEM, $PUBKEYDER), $extract); |
| 88 | + |
| 89 | +/* let's import these keys */ |
| 90 | +sexec(sprintf("pkcs11-tool --login --pin %s --write-object %s --type privkey --label VJPrivKey --module %s", |
| 91 | + $PHP11_PIN, $PRIVKEYDER, $PKCS11_MODULE_PATH), $importpriv); |
| 92 | + |
| 93 | +sexec(sprintf("pkcs11-tool --login --pin %s --write-object %s --type pubkey --label VJPubKey --module %s", |
| 94 | + $PHP11_PIN, $PUBKEYDER, $PKCS11_MODULE_PATH), $importpub); |
| 95 | + |
| 96 | +/* let's build the x509 */ |
| 97 | +sexec(sprintf("openssl req -new -x509 -subj '/CN=MyCertVJ' ". |
| 98 | + "-engine pkcs11 -keyform engine -key 'pkcs11:object=VJPrivKey;type=private;pin-value=%s' ". |
| 99 | + "-outform DER -out %s", $PHP11_PIN, $CERTDER), $req); |
| 100 | +sexec(sprintf("pkcs11-tool --login --pin %s --write-object %s --type cert --label VJCert --module %s", |
| 101 | + $PHP11_PIN, $CERTDER, $PKCS11_MODULE_PATH), $importcert); |
| 102 | + |
| 103 | +/* let's start the tests */ |
| 104 | + |
| 105 | +$key = openssl_pkey_get_private(sprintf("pkcs11:object=VJPrivKey;type=private;pin-value=%s", $PHP11_PIN)); |
| 106 | +if (!($key instanceof OpenSSLAsymmetricKey)) { |
| 107 | + echo "Private Key NOK".PHP_EOL; |
| 108 | + exit(1); |
| 109 | +} |
| 110 | +echo "Private Key OK".PHP_EOL; |
| 111 | + |
| 112 | +$key = openssl_pkey_get_public(sprintf("pkcs11:object=VJPubKey;type=public")); |
| 113 | +if (!($key instanceof OpenSSLAsymmetricKey)) { |
| 114 | + echo "Public Key NOK".PHP_EOL; |
| 115 | + exit(1); |
| 116 | +} |
| 117 | +echo "Public Key OK".PHP_EOL; |
| 118 | + |
| 119 | +$cert = openssl_x509_read(sprintf("pkcs11:object=VJCert;type=cert")); |
| 120 | +if (!($cert instanceof OpenSSLCertificate)) { |
| 121 | + echo "Cert NOK".PHP_EOL; |
| 122 | + exit(1); |
| 123 | +} |
| 124 | +echo "Cert OK".PHP_EOL; |
| 125 | +$certArray=openssl_x509_parse($cert); |
| 126 | + |
| 127 | +if ($certArray['name'] !== "/CN=MyCertVJ") { |
| 128 | + echo "Cert content NOK".PHP_EOL; |
| 129 | + exit(1); |
| 130 | +} |
| 131 | +echo "Cert content OK".PHP_EOL; |
| 132 | + |
| 133 | +?> |
| 134 | +--EXPECT-- |
| 135 | +Private Key OK |
| 136 | +Public Key OK |
| 137 | +Cert OK |
| 138 | +Cert content OK |
0 commit comments