1<?php
2
3/**
4 * SSH2 Signature Handler
5 *
6 * PHP version 5
7 *
8 * Handles signatures in the format used by SSH2
9 *
10 * @category  Crypt
11 * @package   Common
12 * @author    Jim Wigginton <terrafrost@php.net>
13 * @copyright 2016 Jim Wigginton
14 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
15 * @link      http://phpseclib.sourceforge.net
16 */
17
18namespace phpseclib3\Crypt\EC\Formats\Signature;
19
20use phpseclib3\Common\Functions\Strings;
21use phpseclib3\Math\BigInteger;
22
23/**
24 * SSH2 Signature Handler
25 *
26 * @package Common
27 * @author  Jim Wigginton <terrafrost@php.net>
28 * @access  public
29 */
30abstract class SSH2
31{
32    /**
33     * Loads a signature
34     *
35     * @access public
36     * @param string $sig
37     * @return mixed
38     */
39    public static function load($sig)
40    {
41        if (!is_string($sig)) {
42            return false;
43        }
44
45        $result = Strings::unpackSSH2('ss', $sig);
46        if ($result === false) {
47            return false;
48        }
49        list($type, $blob) = $result;
50        switch ($type) {
51            // see https://tools.ietf.org/html/rfc5656#section-3.1.2
52            case 'ecdsa-sha2-nistp256':
53            case 'ecdsa-sha2-nistp384':
54            case 'ecdsa-sha2-nistp521':
55                break;
56            default:
57                return false;
58        }
59
60        $result = Strings::unpackSSH2('ii', $blob);
61        if ($result === false) {
62            return false;
63        }
64
65        return [
66            'r' => $result[0],
67            's' => $result[1]
68        ];
69    }
70
71    /**
72     * Returns a signature in the appropriate format
73     *
74     * @access public
75     * @param \phpseclib3\Math\BigInteger $r
76     * @param \phpseclib3\Math\BigInteger $s
77     * @param string $curve
78     * @return string
79     */
80    public static function save(BigInteger $r, BigInteger $s, $curve)
81    {
82        switch ($curve) {
83            case 'secp256r1':
84                $curve = 'nistp256';
85                break;
86            case 'secp384r1':
87                $curve = 'nistp384';
88                break;
89            case 'secp521r1':
90                $curve = 'nistp521';
91                break;
92            default:
93                return false;
94        }
95
96        $blob = Strings::packSSH2('ii', $r, $s);
97
98        return Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob);
99    }
100}
101