public function testLoadAndFail() { $key = new Key(); $key->generate(); $data_to_sign = "On the whole, I'd rather be in Philadelphia"; $signature = 'This is not the correct signature'; $this->assertFalse($key->verify($data_to_sign, $signature)); }
public function testGettersAndSetters() { $public_contents = file_get_contents($this->pubkey); $private_contents = file_get_contents($this->privkey); $key = new Key(); $key->setPublicKey($public_contents); $this->assertEquals($public_contents, $key->getPublicKey()); $key->setPrivateKey($private_contents); $this->assertEquals($private_contents, $key->getPrivateKey()); }
/** * Verify a HMAC for a request. * * Verifying a HMAC for a request requires knowledge of a key that is shared between * the client and server and should not be disclosed to any third party. * * The request data *should* contain a nonce generated on the client and it * *should* contain a nonce generated on the server. The client nonce should * never have been used before (generated and used once, then discarded), and * the server nonce should have been used exactly once before (generated by * the server, used once and then discarded). These nonces ensure that the * request data is unique even for identical requests. * * An exception is thrown if the signature did not verify or was not present. * * @param array $request_data * @param string $ip_address * * @throws SignatureException * @throws NonceException * * @return void */ public function verifyHMAC(array $request_data, $ip_address = '127.0.0.1') { if (empty($request_data['hmac'])) { throw new SignatureException('No HMAC was present on the request data'); } // Get the data that needs to be verified. $supplied_hmac = $request_data['hmac']; unset($request_data['hmac']); $data_to_verify = http_build_query($request_data); // Verify the client nonce if present. This will normally be created at // the time that the HMAC is created. if (empty($request_data['cnonce'])) { throw new NonceException('No client nonce was present in signature verification'); } $this->verifyClientNonce($request_data['cnonce']); // Create the shared key object $sharedKey = new Key(); $sharedKey->setSharedKey($this->sharedKey); // Verify the signature. $verify = $sharedKey->verify($data_to_verify, $supplied_hmac); if (!$verify) { throw new SignatureException('The HMAC on the request data did not verify'); } // Verify the server nonce if present. Note that the client must request // this. if (!empty($request_data['snonce'])) { $this->verifyServerNonce($request_data['snonce'], $ip_address); } }
/** * Construct a HMAC for a request. * * Creating a HMAC for a request requires knowledge of a key that is shared between * the client and server and should not be disclosed to any third party. * * A client generated nonce is also created and added to the request data. This * *should* (but does not have to be) checked and verified on the server. The nonce * is used to ensure that no two requests have the same data even if the endpoint * and request data are the same. * * The request data *should* (but does not have to) contain a server generated nonce. * The server generated nonce should be used exactly once -- generated on the server, * used by the client and then discarded. * * Adds the following array entities to $request_data: * * * cnonce -- the client generated nonce * * hmac -- the hmac, created with the shared key made by setSharedKey() * * Returns the HMAC * * @param array $request_data * * @return string */ public function createHMAC(array &$request_data) { // Make a nonce $request_data['cnonce'] = $this->createNonce(); // Get the data to be signed. $data_to_sign = http_build_query($request_data); // Create the key $sharedKey = new Key(); $sharedKey->setSharedKey($this->sharedKey); // Create the signature. $base64_hmac = $sharedKey->sign($data_to_sign); $request_data['hmac'] = $base64_hmac; return $base64_hmac; }
public function testSignAndVerify() { $key = new Key(); $key->generate(); $key->store($this->pubkey, $this->privkey); $this->assertTrue(file_exists($this->pubkey)); $this->assertTrue(file_exists($this->privkey)); $client = new Client(); $client->setPrivateKey($this->privkey); $data = ['fox' => 'quick', 'colour' => 'brown', 'dog' => 'lazy']; $signature = $client->createSignature($data); $this->assertNotEmpty($signature); $this->assertTrue(is_string($data['cnonce'])); $this->assertTrue(is_string($data['sig'])); $server = new Server(); $server->setPublicKey($this->pubkey); $server->verifySignature($data); $this->assertTrue(true); // Can't verify without signature unset($data['sig']); try { $server->verifySignature($data); $this->assertTrue(false); } catch (SignatureException $e) { $this->assertTrue(true); } // Can't verify garbage signature $data['sig'] = 'Garbage'; try { $server->verifySignature($data); $this->assertTrue(false); } catch (SignatureException $e) { $this->assertTrue(true); } // Can't verify without cnonce $data = ['fox' => 'quick', 'colour' => 'brown', 'dog' => 'lazy']; $signature = $client->createSignature($data); $this->assertNotEmpty($signature); unset($data['cnonce']); try { $server->verifySignature($data); $this->assertTrue(false); } catch (SignatureException $e) { $this->assertTrue(true); } }