Beispiel #1
0
    /**
     * @group github768
     */
    public function testPSSSigs()
    {
        $rsa = new RSA();
        $rsa->loadKey('-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVx
wTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFnc
CzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0T
p0GbMJDyR4e9T04ZZwIDAQAB
-----END PUBLIC KEY-----');
        $sig = pack('H*', '1bd29a1d704a906cd7f726370ce1c63d8fb7b9a620871a05f3141a311c0d6e75fefb5d36dfb50d3ea2d37cd67992471419bfadd35da6e13b494' . '058ddc9b568d4cfea13ddc3c62b86a6256f5f296980d1131d3eaec6089069a3de79983f73eae20198a18721338b4a66e9cfe80e4f8e4fcef7a5bead5cbb' . 'b8ac4c76adffbc178c');
        $this->assertTrue($rsa->verify('zzzz', $sig));
    }
Beispiel #2
0
 /**
  * Verifies the signature for the specified path.
  *
  * @param string $signaturePath
  * @param string $basePath
  * @param string $certificateCN
  * @return array
  * @throws InvalidSignatureException
  * @throws \Exception
  */
 private function verify($signaturePath, $basePath, $certificateCN)
 {
     if (!$this->isCodeCheckEnforced()) {
         return [];
     }
     $signatureData = json_decode($this->fileAccessHelper->file_get_contents($signaturePath), true);
     if (!is_array($signatureData)) {
         throw new InvalidSignatureException('Signature data not found.');
     }
     $expectedHashes = $signatureData['hashes'];
     ksort($expectedHashes);
     $signature = base64_decode($signatureData['signature']);
     $certificate = $signatureData['certificate'];
     // Check if certificate is signed by ownCloud Root Authority
     $x509 = new \phpseclib\File\X509();
     $rootCertificatePublicKey = $this->fileAccessHelper->file_get_contents($this->environmentHelper->getServerRoot() . '/resources/codesigning/root.crt');
     $x509->loadCA($rootCertificatePublicKey);
     $x509->loadX509($certificate);
     if (!$x509->validateSignature()) {
         throw new InvalidSignatureException('Certificate is not valid.');
     }
     // Verify if certificate has proper CN. "core" CN is always trusted.
     if ($x509->getDN(X509::DN_OPENSSL)['CN'] !== $certificateCN && $x509->getDN(X509::DN_OPENSSL)['CN'] !== 'core') {
         throw new InvalidSignatureException(sprintf('Certificate is not valid for required scope. (Requested: %s, current: %s)', $certificateCN, $x509->getDN(true)));
     }
     // Check if the signature of the files is valid
     $rsa = new \phpseclib\Crypt\RSA();
     $rsa->loadKey($x509->currentCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']);
     $rsa->setSignatureMode(RSA::SIGNATURE_PSS);
     $rsa->setMGFHash('sha512');
     if (!$rsa->verify(json_encode($expectedHashes), $signature)) {
         throw new InvalidSignatureException('Signature could not get verified.');
     }
     // Compare the list of files which are not identical
     $currentInstanceHashes = $this->generateHashes($this->getFolderIterator($basePath), $basePath);
     $differencesA = array_diff($expectedHashes, $currentInstanceHashes);
     $differencesB = array_diff($currentInstanceHashes, $expectedHashes);
     $differences = array_unique(array_merge($differencesA, $differencesB));
     $differenceArray = [];
     foreach ($differences as $filename => $hash) {
         // Check if file should not exist in the new signature table
         if (!array_key_exists($filename, $expectedHashes)) {
             $differenceArray['EXTRA_FILE'][$filename]['expected'] = '';
             $differenceArray['EXTRA_FILE'][$filename]['current'] = $hash;
             continue;
         }
         // Check if file is missing
         if (!array_key_exists($filename, $currentInstanceHashes)) {
             $differenceArray['FILE_MISSING'][$filename]['expected'] = $expectedHashes[$filename];
             $differenceArray['FILE_MISSING'][$filename]['current'] = '';
             continue;
         }
         // Check if hash does mismatch
         if ($expectedHashes[$filename] !== $currentInstanceHashes[$filename]) {
             $differenceArray['INVALID_HASH'][$filename]['expected'] = $expectedHashes[$filename];
             $differenceArray['INVALID_HASH'][$filename]['current'] = $currentInstanceHashes[$filename];
             continue;
         }
         // Should never happen.
         throw new \Exception('Invalid behaviour in file hash comparison experienced. Please report this error to the developers.');
     }
     return $differenceArray;
 }
Beispiel #3
0
 /**
  * Verify with RSASS-PSS + MGF1+SHA256
  * 
  * @param string $message
  * @param string $signature
  * @param PublicKey $rsaPublicKey
  * @return bool
  */
 public static function verify($message, $signature, PublicKey $rsaPublicKey)
 {
     static $rsa = null;
     if (!$rsa) {
         $rsa = new RSA();
         $rsa->setSignatureMode(RSA::SIGNATURE_PSS);
         $rsa->setMGFHash('sha256');
     }
     $rsa->loadKey($rsaPublicKey->getKey());
     return $rsa->verify($message, $signature);
 }
Beispiel #4
0
    /**
     * Validates a signature
     *
     * Returns true if the signature is verified, false if it is not correct or null on error
     *
     * @param string $publicKeyAlgorithm
     * @param string $publicKey
     * @param string $signatureAlgorithm
     * @param string $signature
     * @param string $signatureSubject
     * @access private
     * @return int
     */
    function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
    {
        switch ($publicKeyAlgorithm) {
            case 'rsaEncryption':
                $rsa = new RSA();
                $rsa->loadKey($publicKey);

                switch ($signatureAlgorithm) {
                    case 'md2WithRSAEncryption':
                    case 'md5WithRSAEncryption':
                    case 'sha1WithRSAEncryption':
                    case 'sha224WithRSAEncryption':
                    case 'sha256WithRSAEncryption':
                    case 'sha384WithRSAEncryption':
                    case 'sha512WithRSAEncryption':
                        $rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
                        $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
                        if (!@$rsa->verify($signatureSubject, $signature)) {
                            return false;
                        }
                        break;
                    default:
                        return null;
                }
                break;
            default:
                return null;
        }

        return true;
    }
Beispiel #5
0
 /**
  * Validates a signature
  *
  * Returns true if the signature is verified and false if it is not correct.
  * If the algorithms are unsupposed an exception is thrown.
  *
  * @param string $publicKeyAlgorithm
  * @param string $publicKey
  * @param string $signatureAlgorithm
  * @param string $signature
  * @param string $signatureSubject
  * @access private
  * @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
  * @return bool
  */
 function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
 {
     switch ($publicKeyAlgorithm) {
         case 'rsaEncryption':
             $rsa = new RSA();
             $rsa->load($publicKey);
             switch ($signatureAlgorithm) {
                 case 'md2WithRSAEncryption':
                 case 'md5WithRSAEncryption':
                 case 'sha1WithRSAEncryption':
                 case 'sha224WithRSAEncryption':
                 case 'sha256WithRSAEncryption':
                 case 'sha384WithRSAEncryption':
                 case 'sha512WithRSAEncryption':
                     $rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
                     if (!@$rsa->verify($signatureSubject, $signature, RSA::PADDING_PKCS1)) {
                         return false;
                     }
                     break;
                 default:
                     throw new UnsupportedAlgorithmException('Signature algorithm unsupported');
             }
             break;
         default:
             throw new UnsupportedAlgorithmException('Public key algorithm unsupported');
     }
     return true;
 }
 /**
  *
  * @param string $hashtype        	
  * @param object $key        	
  * @throws OpenIDConnectClientException
  * @return bool
  */
 private function verifyRSAJWTsignature($hashtype, $key, $payload, $signature)
 {
     if (!(property_exists($key, 'n') and property_exists($key, 'e'))) {
         throw new OpenIDConnectClientException('Malformed key object');
     }
     /*
      * We already have base64url-encoded data, so re-encode it as
      * regular base64 and use the XML key format for simplicity.
      */
     var_dump($hashtype, $key, $payload, base64_encode($signature));
     $public_key_xml = "<RSAKeyValue>\r\n" . "  <Modulus>" . b64url2b64($key->n) . "</Modulus>\r\n" . "  <Exponent>" . b64url2b64($key->e) . "</Exponent>\r\n" . "</RSAKeyValue>";
     $rsa = new RSA();
     $rsa->setHash($hashtype);
     $rsa->loadKey($public_key_xml, 'xml');
     $rsa->signatureMode = RSA::SIGNATURE_PKCS1;
     return $rsa->verify($payload, $signature);
 }