Esempio n. 1
0
 /**
  * Verify a signed message with the correct public key
  * 
  * @param string $message Message to verify
  * @param SignaturePublicKey $publicKey
  * @param string $signature
  * @param boolean $raw Don't hex decode the input?
  * @return bool
  * @throws CryptoException\InvalidSignature
  */
 public static function verify(string $message, SignaturePublicKey $publicKey, string $signature, bool $raw = false) : bool
 {
     if (!$raw) {
         $signature = \Sodium\hex2bin($signature);
     }
     if (CryptoUtil::safeStrlen($signature) !== \Sodium\CRYPTO_SIGN_BYTES) {
         throw new CryptoException\InvalidSignature('Signature is not the correct length; is it encoded?');
     }
     return \Sodium\crypto_sign_verify_detached($signature, $message, $publicKey->getRawKeyMaterial());
 }
Esempio n. 2
0
 /**
  * Verify a signed message with the correct public key
  * 
  * @param string $message Message to verify
  * @param Key $publickey
  * @param string $signature
  * @param boolean $raw Don't hex decode the input?
  * 
  * @return boolean
  */
 public static function verify($message, Contract\CryptoKeyInterface $publickey, $signature, $raw = false)
 {
     if (!$publickey->isSigningKey()) {
         throw new CryptoAlert\InvalidKey('Expected a signing key');
     }
     if (!$publickey->isPublicKey()) {
         throw new CryptoAlert\InvalidKey('Expected a public key');
     }
     if (!$raw) {
         $signature = \Sodium\hex2bin($signature);
     }
     return \Sodium\crypto_sign_verify_detached($signature, $message, $publickey->get());
 }
 /**
  * @param string $message
  * @param string $signature
  * @param string $signer_public
  * @return bool
  * @throws SignatureException
  * @throws InvalidTypeException
  */
 public static function verify($message, $signature, $signer_public)
 {
     # Test to make sure all the required variables are strings.
     Helpers::isString($message, 'PublicKeyEncryption', 'verify');
     Helpers::isString($signature, 'PublicKeyEncryption', 'verify');
     Helpers::isString($signer_public, 'PublicKeyEncryption', 'verify');
     # Decode the signature from hex
     $signature = base64_decode(Helpers::hex2bin($signature));
     # Decode the signer's public key from hex
     $signer_public = Helpers::hex2bin($signer_public);
     if (\Sodium\crypto_sign_verify_detached($signature, $message, $signer_public)) {
         return true;
     } else {
         throw new SignatureException('Signature for message invalid.');
     }
 }
Esempio n. 4
0
 /**
  * Verify a signed message with the correct public key
  * 
  * @param string $message Message to verify
  * @param SignaturePublicKey $publicKey
  * @param string $signature
  * @param boolean $raw Don't hex decode the input?
  * 
  * @return boolean
  * 
  * @throws CryptoException\InvalidKey
  * @throws CryptoException\CannotPerformOperation
  */
 public static function verify($message, Contract\KeyInterface $publicKey, $signature, $raw = false)
 {
     if (!$publicKey instanceof SignaturePublicKey) {
         throw new CryptoException\InvalidKey('Argument 2: Expected an instance of SignaturePublicKey');
     }
     if (!$raw) {
         $signature = \Sodium\hex2bin($signature);
     }
     return \Sodium\crypto_sign_verify_detached($signature, $message, $publicKey->get());
 }
Esempio n. 5
0
 /**
  * Check if a password is known by the knownpassword.org API.
  *
  * @param string $password      	The password to check.
  * @param string $passwordFormat    The format of the given password (Blake2b, Sha512, Cleartext) [Default: Blake2b].
  * @return mixed               		Exception on error, true if the password is known and false if the password is unknown.
  * @access public
  */
 public function checkPassword($password, $passwordFormat = "Blake2b")
 {
     $apiData = array();
     switch ($passwordFormat) {
         case "Blake2b":
             $apiData = array("Blake2b" => $password);
             break;
         case "Sha512":
             $apiData = array("Sha512" => $password);
             break;
         case "Cleartext":
             $apiData = array("Cleartext" => $password);
             break;
         default:
             throw new \Exception("Unknown passwordFormat.");
     }
     $nonce = \Sodium\randombytes_buf(24);
     $signature = \Sodium\crypto_sign_detached($nonce, $this->_privatekey);
     $clearJson = json_encode($apiData);
     $encryptionNonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_BOX_NONCEBYTES);
     $encryptionKeyPair = \Sodium\crypto_box_keypair();
     $encryptionSecretkey = \Sodium\crypto_box_secretkey($encryptionKeyPair);
     $encryptionPublickey = \Sodium\crypto_box_publickey($encryptionKeyPair);
     $encryptionKeyPair = \Sodium\crypto_box_keypair_from_secretkey_and_publickey($encryptionSecretkey, $this->_serverEncryptionPublicKey);
     $ciphertext = \Sodium\crypto_box($clearJson, $encryptionNonce, $encryptionKeyPair);
     $encryptedApiData = array("PublicKey" => \Sodium\bin2hex($encryptionPublickey), "Nonce" => \Sodium\bin2hex($encryptionNonce), "Ciphertext" => \Sodium\bin2hex($ciphertext));
     $data_string = json_encode($encryptedApiData);
     $ch = curl_init($this->_apiurl . "/checkpassword");
     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
     curl_setopt($ch, CURLOPT_HEADER, 1);
     curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
     curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($data_string), 'User-Agent: ' . 'Laravel 5', 'X-Public: ' . \Sodium\bin2hex($this->_publickey), 'X-Nonce: ' . \Sodium\bin2hex($nonce), 'X-Signature: ' . \Sodium\bin2hex($signature)));
     if (!($result = curl_exec($ch))) {
         throw new \Exception("Request failed");
     }
     $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
     $header = substr($result, 0, $header_size);
     $headers = $this->get_headers_from_curl_response($header);
     if (array_key_exists("http_code", $headers[0]) && array_key_exists("X-Powered-By", $headers[0]) && array_key_exists("X-Signature", $headers[0])) {
         $httpCode = $headers[0]["http_code"];
         $responsePowered = $headers[0]["X-Powered-By"];
         $responseSignature = $headers[0]["X-Signature"];
         $responseNonce = $headers[0]["X-Nonce"];
         if ($httpCode === "HTTP/1.1 200 OK" || $httpCode === "HTTP/2.0 200 OK") {
             if ($responsePowered === "bitbeans") {
                 // validate the response signature
                 if (!\Sodium\crypto_sign_verify_detached(\Sodium\hex2bin($responseSignature), \Sodium\crypto_generichash(\Sodium\hex2bin($responseNonce), null, 64), $this->_serverSignaturePublicKey)) {
                     throw new \Exception("Invalid signature");
                 }
             } else {
                 throw new \Exception("Invalid server");
             }
         } else {
             throw new \Exception("Invalid response code");
         }
     } else {
         throw new \Exception("Invalid header");
     }
     $result = substr($result, $header_size);
     curl_close($ch);
     $resultJson = json_decode($result);
     $decryptionKeyPair = \Sodium\crypto_box_keypair_from_secretkey_and_publickey($encryptionSecretkey, \Sodium\hex2bin($resultJson->{'publicKey'}));
     $plaintext = \Sodium\crypto_box_open(\Sodium\hex2bin($resultJson->{'ciphertext'}), \Sodium\hex2bin($resultJson->{'nonce'}), $decryptionKeyPair);
     if ($plaintext === FALSE) {
         throw new \Exception("Malformed message or invalid MAC");
     }
     $plaintextJson = json_decode($plaintext);
     return !$plaintextJson->{'FoundPassword'};
 }
Esempio n. 6
0
 /**
  * Verify a signed message with the correct public key
  * 
  * @param string $message Message to verify
  * @param SignaturePublicKey $publicKey
  * @param string $signature
  * @param mixed $encoding Which encoding scheme to use?
  * @return bool
  * @throws InvalidSignature
  */
 public static function verify(string $message, SignaturePublicKey $publicKey, string $signature, $encoding = Halite::ENCODE_BASE64URLSAFE) : bool
 {
     $decoder = Halite::chooseEncoder($encoding, true);
     if ($decoder) {
         // We were given hex data:
         $signature = $decoder($signature);
     }
     if (CryptoUtil::safeStrlen($signature) !== \Sodium\CRYPTO_SIGN_BYTES) {
         throw new InvalidSignature('Signature is not the correct length; is it encoded?');
     }
     return \Sodium\crypto_sign_verify_detached($signature, $message, $publicKey->getRawKeyMaterial());
 }
Esempio n. 7
0
 /**
  * Checks if the ticket has been authenticated.
  * Verifies user signature if libsodium is available.
  *
  * @return Returns an associative array containing user_id and aux data, or a WP_Error instance on error.
  */
 static function verify_authentication($ticketid, $purpose, $nonce)
 {
     # Prepare parameters
     $params = "ticket-id=" . urlencode($ticketid);
     # Invoke API
     $cont = @file_get_contents("https://api.verifyne.me/v1/ticket-state?" . $params);
     if (FALSE === $cont) {
         return new WP_Error("verifyne", "Failed to query verifyne API");
     }
     # Read JSON
     $resp = @json_decode($cont);
     if (NULL === $resp) {
         return new WP_Error("verifyne", "Invalid JSON received");
     }
     # Check result
     if ($resp->result->code !== 0) {
         return new WP_Error("verifyne", $resp->result->description);
     }
     # Extract content
     $ticket = $resp->content;
     # Sanity checks
     if ($ticket->id !== $ticketid || $ticket->purpose !== $purpose || $ticket->nonce !== $nonce) {
         return new WP_Error("verifyne", "Received invalid data from verifyne server");
     }
     # We can verify the cryptographic signatures :)
     if (extension_loaded('libsodium')) {
         #<provider_signature>:<type>:<id>:<expires>:<nonce>:<purpose>
         $payload = $ticket->provider_signature . ":" . $ticket->type . ":" . $ticket->id . ":" . $ticket->expires . ":" . $ticket->nonce . ":" . $ticket->purpose;
         $signature = base64_decode($ticket->user_signature, $strict = true);
         if (FALSE === $signature) {
             return new WP_Error("verifyne", "Undecodable user signature");
         }
         $user_key = base64_decode($ticket->user_id, $strict = true);
         if (FALSE === $user_key) {
             return new WP_Error("verifyne", "Undecodable user key");
         }
         # Check user signature
         if (TRUE !== @\Sodium\crypto_sign_verify_detached($signature, $payload, $user_key)) {
             return new WP_Error("verifyne", "Invalid user signature");
         }
         # User signature is legit :)
     }
     return array("userid" => $ticket->user_id, "aux" => $ticket->aux);
 }