Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php
12256 views
1
<?php
2
3
/**
4
* Data structure representing a raw public key.
5
*/
6
final class PhabricatorAuthSSHPublicKey extends Phobject {
7
8
private $type;
9
private $body;
10
private $comment;
11
12
private function __construct() {
13
// <internal>
14
}
15
16
public static function newFromStoredKey(PhabricatorAuthSSHKey $key) {
17
$public_key = new PhabricatorAuthSSHPublicKey();
18
$public_key->type = $key->getKeyType();
19
$public_key->body = $key->getKeyBody();
20
$public_key->comment = $key->getKeyComment();
21
22
return $public_key;
23
}
24
25
public static function newFromRawKey($entire_key) {
26
$entire_key = trim($entire_key);
27
if (!strlen($entire_key)) {
28
throw new Exception(pht('No public key was provided.'));
29
}
30
31
$parts = str_replace("\n", '', $entire_key);
32
33
// The third field (the comment) can have spaces in it, so split this
34
// into a maximum of three parts.
35
$parts = preg_split('/\s+/', $parts, 3);
36
37
if (preg_match('/private\s*key/i', $entire_key)) {
38
// Try to give the user a better error message if it looks like
39
// they uploaded a private key.
40
throw new Exception(pht('Provide a public key, not a private key!'));
41
}
42
43
switch (count($parts)) {
44
case 1:
45
throw new Exception(
46
pht('Provided public key is not properly formatted.'));
47
case 2:
48
// Add an empty comment part.
49
$parts[] = '';
50
break;
51
case 3:
52
// This is the expected case.
53
break;
54
}
55
56
list($type, $body, $comment) = $parts;
57
58
$recognized_keys = array(
59
'ssh-dsa',
60
'ssh-dss',
61
'ssh-rsa',
62
'ssh-ed25519',
63
'ecdsa-sha2-nistp256',
64
'ecdsa-sha2-nistp384',
65
'ecdsa-sha2-nistp521',
66
);
67
68
if (!in_array($type, $recognized_keys)) {
69
$type_list = implode(', ', $recognized_keys);
70
throw new Exception(
71
pht(
72
'Public key type should be one of: %s',
73
$type_list));
74
}
75
76
$public_key = new PhabricatorAuthSSHPublicKey();
77
$public_key->type = $type;
78
$public_key->body = $body;
79
$public_key->comment = $comment;
80
81
return $public_key;
82
}
83
84
public function getType() {
85
return $this->type;
86
}
87
88
public function getBody() {
89
return $this->body;
90
}
91
92
public function getComment() {
93
return $this->comment;
94
}
95
96
public function getHash() {
97
$body = $this->getBody();
98
$body = trim($body);
99
$body = rtrim($body, '=');
100
return PhabricatorHash::digestForIndex($body);
101
}
102
103
public function getEntireKey() {
104
$key = $this->type.' '.$this->body;
105
if (strlen($this->comment)) {
106
$key = $key.' '.$this->comment;
107
}
108
return $key;
109
}
110
111
public function toPKCS8() {
112
$entire_key = $this->getEntireKey();
113
$cache_key = $this->getPKCS8CacheKey($entire_key);
114
115
$cache = PhabricatorCaches::getImmutableCache();
116
$pkcs8_key = $cache->getKey($cache_key);
117
if ($pkcs8_key) {
118
return $pkcs8_key;
119
}
120
121
$tmp = new TempFile();
122
Filesystem::writeFile($tmp, $this->getEntireKey());
123
try {
124
list($pkcs8_key) = execx(
125
'ssh-keygen -e -m PKCS8 -f %s',
126
$tmp);
127
} catch (CommandException $ex) {
128
unset($tmp);
129
throw new PhutilProxyException(
130
pht(
131
'Failed to convert public key into PKCS8 format. If you are '.
132
'developing on OSX, you may be able to use `%s` '.
133
'to work around this issue. %s',
134
'bin/auth cache-pkcs8',
135
$ex->getMessage()),
136
$ex);
137
}
138
unset($tmp);
139
140
$cache->setKey($cache_key, $pkcs8_key);
141
142
return $pkcs8_key;
143
}
144
145
public function forcePopulatePKCS8Cache($pkcs8_key) {
146
$entire_key = $this->getEntireKey();
147
$cache_key = $this->getPKCS8CacheKey($entire_key);
148
149
$cache = PhabricatorCaches::getImmutableCache();
150
$cache->setKey($cache_key, $pkcs8_key);
151
}
152
153
private function getPKCS8CacheKey($entire_key) {
154
return 'pkcs8:'.PhabricatorHash::digestForIndex($entire_key);
155
}
156
157
}
158
159