1<?php
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/**
19 * Signs data.
20 *
21 * Only used for testing.
22 *
23 * @author Brian Eaton <beaton@google.com>
24 */
25class Google_P12Signer extends Google_Signer {
26  // OpenSSL private key resource
27  private $privateKey;
28
29  // Creates a new signer from a .p12 file.
30  function __construct($p12, $password) {
31    if (!function_exists('openssl_x509_read')) {
32      throw new Exception(
33          'The Google PHP API library needs the openssl PHP extension');
34    }
35
36    // This throws on error
37    $certs = array();
38    if (!openssl_pkcs12_read($p12, $certs, $password)) {
39      throw new Google_AuthException("Unable to parse the p12 file.  " .
40          "Is this a .p12 file?  Is the password correct?  OpenSSL error: " .
41          openssl_error_string());
42    }
43    // TODO(beaton): is this part of the contract for the openssl_pkcs12_read
44    // method?  What happens if there are multiple private keys?  Do we care?
45    if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) {
46      throw new Google_AuthException("No private key found in p12 file.");
47    }
48    $this->privateKey = openssl_pkey_get_private($certs["pkey"]);
49    if (!$this->privateKey) {
50      throw new Google_AuthException("Unable to load private key in ");
51    }
52  }
53
54  function __destruct() {
55    if ($this->privateKey) {
56      openssl_pkey_free($this->privateKey);
57    }
58  }
59
60  function sign($data) {
61    if(version_compare(PHP_VERSION, '5.3.0') < 0) {
62      throw new Google_AuthException(
63        "PHP 5.3.0 or higher is required to use service accounts.");
64    }
65    if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
66      throw new Google_AuthException("Unable to sign data");
67    }
68    return $signature;
69  }
70}
71