Overview
Comment: | Added support for x509v3-ssh-rsa and x509v3-sign-rsa to agent |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 648368d41d22147a0a1d77ff4ceb6df70a6f81f7 |
User & Date: | rkeene on 2019-01-31 15:04:33 |
Other Links: | manifest | tags |
Context
2019-02-04
| ||
17:32 | More X.509v3 support for SSH agent check-in: 0defa19481 user: rkeene tags: trunk | |
2019-01-31
| ||
15:04 | Added support for x509v3-ssh-rsa and x509v3-sign-rsa to agent check-in: 648368d41d user: rkeene tags: trunk | |
13:29 | Ensure externally connectable IDs are present check-in: e04736eb53 user: rkeene tags: trunk | |
Changes
Modified build/chrome/ssh-agent.js from [2a1297f569] to [d4659c8b69].
2 2 * CACKey SSH Agent for ChromeOS 3 3 */ 4 4 5 5 cackeySSHAgentApprovedApps = [ 6 6 "pnhechapfaindjhompbnflcldabbghjo", 7 7 "okddffdblfhhnmhodogpojmfkjmhinfp" 8 8 ]; 9 + 10 +/* 11 + * XXX:TODO: Expose UI for this 12 + */ 13 +cackeySSHAgentFeatures = { 14 + enabled: true, 15 + includeKeys: true, 16 + includeCerts: true, 17 + legacy: false 18 +}; 19 + 20 +/* 21 + * Feature support checking 22 + */ 23 +function cackeySSHAgentGetSSHKeyTypes() { 24 + var types = []; 25 + 26 + if (cackeySSHAgentFeatures.includeKeys) { 27 + types.push("ssh"); 28 + } 29 + 30 + if (cackeySSHAgentFeatures.includeCerts) { 31 + types.push("x509v3-ssh"); 32 + 33 + if (cackeySSHAgentFeatures.legacy) { 34 + types.push("x509v3-sign"); 35 + } 36 + } 37 + 38 + return(types); 39 +} 40 + 41 +async function cackeySSHAgentGetCertificates() { 42 + var certs; 43 + 44 + if (!cackeySSHAgentFeatures.enabled) { 45 + return([]); 46 + } 47 + 48 + certs = await cackeyListCertificates(); 49 + 50 + return(certs); 51 +} 9 52 10 53 /* 11 54 * SSH Element Encoding/Decoding 12 55 */ 13 56 function cackeySSHAgentEncodeInt(uint32) { 14 57 var result; 15 58 ................................................................................ 46 89 while (bigInt) { 47 90 result.push(bigInt & 0xff); 48 91 bigInt = bigInt >> 8; 49 92 } 50 93 result.reverse(); 51 94 break; 52 95 case "object": 53 - result = []; 54 - new Uint8Array(bigInt.toByteArray()).forEach(function(e) { 55 - result.push(e); 56 - }); 96 + result = Array.from(new Uint8Array(bigInt.toByteArray())); 57 97 break; 58 98 } 59 99 60 100 result = cackeySSHAgentEncodeLV(result); 61 101 62 102 return(result); 63 103 } ................................................................................ 84 124 result = input.slice(0, info.value); 85 125 86 126 return({ 87 127 value: result, 88 128 output: input.slice(info.value) 89 129 }); 90 130 } 131 + 132 +function cackeySSHAgentEncodeArray(input) { 133 + var result; 134 + 135 + result = cackeySSHAgentEncodeInt(input.length); 136 + input.forEach(function(element) { 137 + result = result.concat(element); 138 + }); 139 + 140 + return(result); 141 +} 91 142 92 143 function cackeySSHAgentEncodeToUTF8Array(str) { 93 144 var utf8 = []; 94 145 95 146 if (typeof(str) === "string") { 96 147 str = str.split("").map(function(c) { 97 148 return(c.charCodeAt(0)); ................................................................................ 154 205 buffer = buffer.join(""); 155 206 break; 156 207 } 157 208 158 209 return(buffer); 159 210 } 160 211 161 -function cackeySSHAgentEncodeCertToKeyAndID(cert) { 212 +function cackeySSHAgentEncodeCertToKeyAndID(cert, keyType) { 162 213 var result = null, resultKey = null; 163 - var certObj; 214 + var certObj, certBytes; 164 215 var publicKey; 165 216 166 217 certObj = new X509; 167 218 if (!certObj) { 168 219 return(result); 169 220 } 170 221 171 - certObj.readCertHex(cackeySSHAgentEncodeBinaryToHex(cert)); 222 + certBytes = Array.from(new Uint8Array(cert)); 223 + 224 + certObj.readCertHex(cackeySSHAgentEncodeBinaryToHex(certBytes)); 172 225 173 226 publicKey = certObj.getPublicKey(); 174 227 175 - switch (publicKey.type) { 176 - case "RSA": 177 - resultKey = cackeySSHAgentEncodeString("ssh-rsa"); 178 - resultKey = resultKey.concat(cackeySSHAgentEncodeBigInt(publicKey.e)); 179 - resultKey = resultKey.concat(cackeySSHAgentEncodeBigInt(publicKey.n)); 228 + switch (keyType) { 229 + case "ssh": 230 + switch (publicKey.type) { 231 + case "RSA": 232 + resultKey = cackeySSHAgentEncodeString("ssh-rsa"); 233 + resultKey = resultKey.concat(cackeySSHAgentEncodeBigInt(publicKey.e)); 234 + resultKey = resultKey.concat(cackeySSHAgentEncodeBigInt(publicKey.n)); 235 + break; 236 + default: 237 + console.log("[cackeySSH] Unsupported public key type:", keyType, "/", publicKey.type, "-- ignoring."); 238 + break; 239 + } 240 + break; 241 + case "x509v3-sign": 242 + resultKey = certBytes; 243 + break; 244 + case "x509v3-ssh": 245 + switch (publicKey.type) { 246 + case "RSA": 247 + resultKey = cackeySSHAgentEncodeString("x509v3-ssh-rsa"); 248 + 249 + /* 250 + * Array of certificates 251 + */ 252 + resultKey = resultKey.concat(cackeySSHAgentEncodeArray([ 253 + cackeySSHAgentEncodeLV(certBytes) 254 + ])); 255 + 256 + /* 257 + * Array of OCSP responses 258 + */ 259 + resultKey = resultKey.concat(cackeySSHAgentEncodeArray([])); 260 + break; 261 + default: 262 + console.log("[cackeySSH] Unsupported public key type:", keyType, "/", publicKey.type, "-- ignoring."); 263 + break; 264 + } 180 265 break; 181 266 default: 182 - console.log("[cackeySSH] Unsupported public key type:", publicKey.type, "-- ignoring."); 267 + console.log("[cackeySSH] Unsupported SSH key type:", keyType, "-- ignoring."); 268 + break; 183 269 } 184 270 185 271 if (resultKey) { 186 272 result = { 187 273 id: certObj.getSubjectString(), 188 - type: publicKey.type, 274 + publicKeyType: publicKey.type, 275 + sshKeyType: keyType, 189 276 key: resultKey 190 277 }; 191 278 } 192 279 193 280 return(result); 194 281 } 195 282 ................................................................................ 200 287 var response; 201 288 var certs = []; 202 289 var keys = []; 203 290 204 291 /* 205 292 * Get a list of certificates 206 293 */ 207 - certs = await cackeyListCertificates(); 294 + certs = await cackeySSHAgentGetCertificates(); 208 295 209 296 /* 210 297 * Convert each certificate to an SSH key blob 211 298 */ 212 - certs.forEach(function(cert) { 213 - var key; 299 + cackeySSHAgentGetSSHKeyTypes().forEach(function(sshKeyType) { 300 + certs.forEach(function(cert) { 301 + var key; 214 302 215 - key = cackeySSHAgentEncodeCertToKeyAndID(cert.certificate); 303 + key = cackeySSHAgentEncodeCertToKeyAndID(cert.certificate, sshKeyType); 216 304 217 - if (key) { 218 - keys.push(key); 219 - } 305 + if (key) { 306 + keys.push(key); 307 + } 308 + }); 220 309 }); 221 310 222 311 /* 223 312 * Encode response 224 313 */ 225 314 response = []; 226 315 ................................................................................ 269 358 flags = cackeySSHAgentDecodeInt(request); 270 359 request = flags.output; 271 360 flags = flags.value; 272 361 273 362 /* 274 363 * Find the certificate that matches the requested key 275 364 */ 276 - certs = await cackeyListCertificates(); 365 + certs = await cackeySSHAgentGetCertificates(); 277 366 certToUse = null; 278 - certs.forEach(function(cert) { 279 - var key; 367 + cackeySSHAgentGetSSHKeyTypes().forEach(function(sshKeyType) { 368 + certs.forEach(function(cert) { 369 + var key; 280 370 281 - key = cackeySSHAgentEncodeCertToKeyAndID(cert.certificate); 371 + key = cackeySSHAgentEncodeCertToKeyAndID(cert.certificate, sshKeyType); 282 372 283 - if (key.key.join() == keyInfo.join()) { 284 - certToUse = cert; 285 - certToUseType = key.type; 286 - } 373 + if (key.key.join() == keyInfo.join()) { 374 + certToUse = cert; 375 + certToUseType = key.publicKeyType; 376 + } 377 + }); 287 378 }); 288 379 289 380 /* 290 381 * If no certificate is found, return an error 291 382 */ 292 383 if (!certToUse) { 293 384 console.info("[cackeySSH] Unable to find a certificate to match the requested key:", keyInfo);