web-ssh-keygen
Advanced tools
Comparing version 0.1.0 to 0.1.1
@@ -8,2 +8,6 @@ # Changelog | ||
## [0.1.1] - 2020-02-10 | ||
### Changed | ||
- Improve internal typings | ||
## 0.1.0 - 2020-02-09 | ||
@@ -13,2 +17,3 @@ ### Added | ||
[Unreleased]: https://github.com/nwtgck/binconv-npm/compare/v0.1.0...HEAD | ||
[Unreleased]: https://github.com/nwtgck/binconv-npm/compare/v0.1.1...HEAD | ||
[0.1.1]: https://github.com/nwtgck/binconv-npm/compare/v0.1.0...v0.1.1 |
@@ -1,3 +0,3 @@ | ||
export declare function arrayToPem(a: any[]): string; | ||
export declare function pemToArray(pem: string): any[]; | ||
export declare function arrayToPem(a: number[]): string; | ||
export declare function pemToArray(pem: string): number[]; | ||
export declare function pkcs1To8(privateKeyPkcs1Pem: string): string; |
@@ -26,3 +26,3 @@ "use strict"; | ||
function stringToArray(s) { | ||
return s.split("").map(c => c.charCodeAt()); | ||
return s.split("").map(c => c.charCodeAt(0)); | ||
} | ||
@@ -29,0 +29,0 @@ function pemToArray(pem) { |
@@ -1,2 +0,2 @@ | ||
export declare function arrayToString(a: any): string; | ||
export declare function arrayToString(a: number[]): string; | ||
export declare function publicSshToPem(publicKey: string): string; |
@@ -56,3 +56,3 @@ "use strict"; | ||
function stringToArray(s) { | ||
return s.split("").map(c => c.charCodeAt()); | ||
return s.split("").map(c => c.charCodeAt(0)); | ||
} | ||
@@ -59,0 +59,0 @@ function pemToArray(pem) { |
@@ -1,15 +0,18 @@ | ||
export declare function stringToArray(s: string): any[]; | ||
export declare function base64urlToArray(s: string): any[]; | ||
export declare function arrayToLen(a: any[]): number; | ||
export declare function arrayToString(a: number[]): string; | ||
export declare function stringToArray(s: string): number[]; | ||
export declare function base64urlToArray(s: string): number[]; | ||
export declare function pemToArray(pem: string): number[]; | ||
export declare function arrayToPem(a: readonly number[]): string; | ||
export declare function arrayToLen(a: readonly number[]): number; | ||
export declare function integerToOctet(n: number): number[]; | ||
export declare function lenToArray(n: number): number[]; | ||
export declare function decodePublicKey(s: string): { | ||
type: string; | ||
exponent: any[]; | ||
key: any[]; | ||
type: 'ssh-rsa'; | ||
exponent: number[]; | ||
key: number[]; | ||
name: string; | ||
}; | ||
export declare function checkHighestBit(v: any[]): any[]; | ||
export declare function encodePublicKey(jwk: any, name: string): string; | ||
export declare function checkHighestBit(v: number[]): number[]; | ||
export declare function encodePublicKey(jwk: JsonWebKey, name: string): string; | ||
export declare function asnEncodeLen(n: number): number[]; | ||
export declare function encodePrivateKey(jwk: any): string; | ||
export declare function encodePrivateKey(jwk: JsonWebKey): string; |
@@ -7,4 +7,5 @@ "use strict"; | ||
} | ||
exports.arrayToString = arrayToString; | ||
function stringToArray(s) { | ||
return s.split("").map(c => c.charCodeAt()); | ||
return s.split("").map(c => c.charCodeAt(0)); | ||
} | ||
@@ -19,5 +20,7 @@ exports.stringToArray = stringToArray; | ||
} | ||
exports.pemToArray = pemToArray; | ||
function arrayToPem(a) { | ||
return window.btoa(a.map((c) => String.fromCharCode(c)).join("")); | ||
return window.btoa(a.map(c => String.fromCharCode(c)).join("")); | ||
} | ||
exports.arrayToPem = arrayToPem; | ||
function arrayToLen(a) { | ||
@@ -88,3 +91,5 @@ let result = 0; | ||
const typeLenA = lenToArray(k.type.length); | ||
const array = [].concat(typeLenA, stringToArray(k.type), exponentLenA, k.exponent, keyLenA, k.key); | ||
const array = [ | ||
...typeLenA, ...stringToArray(k.type), ...exponentLenA, ...k.exponent, ...keyLenA, ...k.key, | ||
]; | ||
const encoding = arrayToPem(array); | ||
@@ -91,0 +96,0 @@ return `${k.type} ${encoding} ${k.name}`; |
{ | ||
"name": "web-ssh-keygen", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"description": "Generate ssh-keygen keys using the WebCrypto API", | ||
@@ -35,3 +35,3 @@ "main": "./dist/src/index.js", | ||
"type": "git", | ||
"url": "https://github.com/nwtgck/ssh-keygen-npm" | ||
"url": "https://github.com/nwtgck/web-ssh-keygen" | ||
}, | ||
@@ -38,0 +38,0 @@ "author": "patrick@roumanoff.com, Ryo Ota <nwtgck@nwtgck.org> (https://github.com/nwtgck)", |
# web-ssh-keygen | ||
[](https://circleci.com/gh/nwtgck/ssh-keygen-npm) | ||
[](https://www.npmjs.com/package/web-ssh-keygen) [](https://circleci.com/gh/nwtgck/web-ssh-keygen) | ||
@@ -8,1 +8,6 @@ Generate a key-pair of `ssh-keygen` on Web | ||
The original version was created by [Patrick Roumanoff](http://blog.roumanoff.com/). Thanks! The original repository is found on [PatrickRoumanoff/js-keygen](https://github.com/PatrickRoumanoff/js-keygen). He made the core logic of this repository. | ||
## Web App | ||
<https://ssh-keygen.netlify.com> | ||
GitHub repo: <https://github.com/nwtgck/ssh-keygen-web> |
@@ -1,6 +0,5 @@ | ||
/* global encodePrivateKey, encodePublicKey */ | ||
import {encodePrivateKey, encodePublicKey} from './ssh-util'; | ||
const extractable = true; | ||
function wrap(text: string, len: number): string { | ||
function wrap(text: string, len?: number): string { | ||
const length = len || 72; | ||
@@ -47,6 +46,4 @@ let result = ""; | ||
.then(encodePrivateKey) | ||
// TODO: any | ||
.then((wrap as any)) | ||
// TODO: any | ||
.then((rsaPrivateKey as any)); | ||
.then(wrap) | ||
.then(rsaPrivateKey); | ||
@@ -53,0 +50,0 @@ const publicKeyPromise = window.crypto.subtle.exportKey("jwk", key.publicKey).then(jwk => encodePublicKey(jwk, name)); |
@@ -1,4 +0,2 @@ | ||
/* eslint no-bitwise: 0 */ | ||
function wrap(text: string, len: number) { | ||
function wrap(text: string, len?: number): string { | ||
const length = len || 72; | ||
@@ -13,8 +11,7 @@ let result = ""; | ||
// TODO: any | ||
function pemPrivateKey(key: any) { | ||
function pemPrivateKey(key: string): string { | ||
return `-----BEGIN PRIVATE KEY-----\n${wrap(key, 64)}-----END PRIVATE KEY-----`; | ||
} | ||
function stripPemFormatting(str: string) { | ||
function stripPemFormatting(str: string): string { | ||
return str | ||
@@ -25,13 +22,12 @@ .replace(/^-----BEGIN (?:RSA )?(?:PRIVATE|PUBLIC) KEY-----$/m, "") | ||
} | ||
// TODO: any | ||
export function arrayToPem(a: any[]) { | ||
export function arrayToPem(a: number[]): string { | ||
return window.btoa(a.map(c => String.fromCharCode(c)).join("")); | ||
} | ||
function stringToArray(s: string) { | ||
// TODO: any | ||
return s.split("").map(c => (c as any).charCodeAt()); | ||
function stringToArray(s: string): number[] { | ||
return s.split("").map(c => c.charCodeAt(0)); | ||
} | ||
export function pemToArray(pem: string) { | ||
export function pemToArray(pem: string): number[] { | ||
return stringToArray(window.atob(pem)); | ||
@@ -69,3 +65,3 @@ } | ||
export function pkcs1To8(privateKeyPkcs1Pem: string) { | ||
export function pkcs1To8(privateKeyPkcs1Pem: string): string { | ||
const pem = stripPemFormatting(privateKeyPkcs1Pem); | ||
@@ -72,0 +68,0 @@ const privateKeyPkcs1Array = pemToArray(pem); |
@@ -1,4 +0,2 @@ | ||
/* eslint no-bitwise: 0 */ | ||
function wrap(text: string, len: number) { | ||
function wrap(text: string, len?: number): string { | ||
const length = len || 72; | ||
@@ -13,7 +11,7 @@ let result = ""; | ||
function pemPublicKey(key: string) { | ||
function pemPublicKey(key: string): string { | ||
return `---- BEGIN RSA PUBLIC KEY ----\n${wrap(key, 65)}---- END RSA PUBLIC KEY ----`; | ||
} | ||
function integerToOctet(n: number) { | ||
function integerToOctet(n: number): number[] { | ||
const result = []; | ||
@@ -26,3 +24,3 @@ for (let i = n; i > 0; i >>= 8) { | ||
function asnEncodeLen(n: number) { | ||
function asnEncodeLen(n: number): number[] { | ||
let result = []; | ||
@@ -38,4 +36,3 @@ if (n >> 7) { | ||
// TODO: any | ||
function checkHighestBit(v: any[]) { | ||
function checkHighestBit(v: number[]): number[] { | ||
if (v[0] >> 7 === 1) { | ||
@@ -47,4 +44,3 @@ v.unshift(0); // add leading zero if first bit is set | ||
// TODO: any | ||
function asn1Int(int: any) { | ||
function asn1Int(int: number[]): number[] { | ||
const v = checkHighestBit(int); | ||
@@ -55,4 +51,3 @@ const len = asnEncodeLen(v.length); | ||
// TODO: any | ||
function asn1Seq(seq: any) { | ||
function asn1Seq(seq: readonly number[]): number[] { | ||
const len = asnEncodeLen(seq.length); | ||
@@ -62,22 +57,19 @@ return [0x30].concat(len, seq); // seq tag is 0x30 | ||
// TODO: any | ||
function arrayToPem(a: any[]) { | ||
function arrayToPem(a: number[]): string { | ||
return window.btoa(a.map(c => String.fromCharCode(c)).join("")); | ||
} | ||
// TODO: any | ||
export function arrayToString(a: any) { | ||
export function arrayToString(a: number[]): string { | ||
return String.fromCharCode.apply(null, a); | ||
} | ||
function stringToArray(s: string) { | ||
// TODO: any | ||
return s.split("").map(c => (c as any).charCodeAt()); | ||
function stringToArray(s: string): number[] { | ||
return s.split("").map(c => c.charCodeAt(0)); | ||
} | ||
function pemToArray(pem: string) { | ||
function pemToArray(pem: string): number[] { | ||
return stringToArray(window.atob(pem)); | ||
} | ||
function arrayToLen(a: number[]) { | ||
function arrayToLen(a: number[]): number { | ||
let result = 0; | ||
@@ -90,3 +82,3 @@ for (let i = 0; i < a.length; i += 1) { | ||
function decodePublicKey(s: string) { | ||
function decodePublicKey(s: string): {type: 'ssh-rsa', exponent: number[], key: number[], name: string} { | ||
const split = s.split(" "); | ||
@@ -93,0 +85,0 @@ const prefix = split[0]; |
@@ -1,31 +0,25 @@ | ||
/* eslint no-bitwise: 0 */ | ||
/* global base64urlDecode */ | ||
import {base64urlDecode} from './base64url'; | ||
// TODO: any | ||
function arrayToString(a: any[]) { | ||
export function arrayToString(a: number[]): string { | ||
return String.fromCharCode.apply(null, a); | ||
} | ||
export function stringToArray(s: string) { | ||
// TODO: any | ||
return s.split("").map(c => (c as any).charCodeAt()); | ||
export function stringToArray(s: string): number[] { | ||
return s.split("").map(c => c.charCodeAt(0)); | ||
} | ||
export function base64urlToArray(s: string) { | ||
export function base64urlToArray(s: string): number[] { | ||
return stringToArray(base64urlDecode(s)); | ||
} | ||
function pemToArray(pem: string) { | ||
export function pemToArray(pem: string): number[] { | ||
return stringToArray(window.atob(pem)); | ||
} | ||
// TODO: any | ||
function arrayToPem(a: any) { | ||
// TODO: any | ||
return window.btoa(a.map((c: any) => String.fromCharCode(c)).join("")); | ||
export function arrayToPem(a: readonly number[]): string { | ||
return window.btoa(a.map(c => String.fromCharCode(c)).join("")); | ||
} | ||
// TODO: any | ||
export function arrayToLen(a: any[]) { | ||
export function arrayToLen(a: readonly number[]): number { | ||
let result = 0; | ||
@@ -38,3 +32,3 @@ for (let i = 0; i < a.length; i += 1) { | ||
export function integerToOctet(n: number) { | ||
export function integerToOctet(n: number): number[] { | ||
const result = []; | ||
@@ -47,3 +41,3 @@ for (let i = n; i > 0; i >>= 8) { | ||
export function lenToArray(n: number) { | ||
export function lenToArray(n: number): number[] { | ||
const oct = integerToOctet(n); | ||
@@ -57,3 +51,3 @@ let i; | ||
export function decodePublicKey(s: string) { | ||
export function decodePublicKey(s: string): {type: 'ssh-rsa', exponent: number[], key: number[], name: string} { | ||
const split = s.split(" "); | ||
@@ -77,4 +71,3 @@ const prefix = split[0]; | ||
// TODO: any | ||
export function checkHighestBit(v: any[]) { | ||
export function checkHighestBit(v: number[]) { | ||
if (v[0] >> 7 === 1) { | ||
@@ -87,14 +80,12 @@ // add leading zero if first bit is set | ||
// TODO: any | ||
function jwkToInternal(jwk: any) { | ||
function jwkToInternal(jwk: JsonWebKey) { | ||
return { | ||
type: "ssh-rsa", | ||
exponent: checkHighestBit(stringToArray(base64urlDecode(jwk.e))), | ||
exponent: checkHighestBit(stringToArray(base64urlDecode(jwk.e!))), | ||
name: "name", | ||
key: checkHighestBit(stringToArray(base64urlDecode(jwk.n))), | ||
key: checkHighestBit(stringToArray(base64urlDecode(jwk.n!))), | ||
}; | ||
} | ||
// TODO: any | ||
export function encodePublicKey(jwk: any, name: string) { | ||
export function encodePublicKey(jwk: JsonWebKey, name: string): string { | ||
const k = jwkToInternal(jwk); | ||
@@ -105,5 +96,5 @@ k.name = name; | ||
const typeLenA = lenToArray(k.type.length); | ||
// TODO: remove ignore | ||
// @ts-ignore | ||
const array = [].concat((typeLenA as any), stringToArray(k.type), exponentLenA, k.exponent, keyLenA, k.key); | ||
const array = [ | ||
...typeLenA, ...stringToArray(k.type), ...exponentLenA, ...k.exponent, ...keyLenA, ...k.key, | ||
]; | ||
const encoding = arrayToPem(array); | ||
@@ -113,3 +104,3 @@ return `${k.type} ${encoding} ${k.name}`; | ||
export function asnEncodeLen(n: number) { | ||
export function asnEncodeLen(n: number): number[] { | ||
let result = []; | ||
@@ -125,7 +116,6 @@ if (n >> 7) { | ||
// TODO: any | ||
export function encodePrivateKey(jwk: any) { | ||
const order = ["n", "e", "d", "p", "q", "dp", "dq", "qi"]; | ||
export function encodePrivateKey(jwk: JsonWebKey): string { | ||
const order = ["n", "e", "d", "p", "q", "dp", "dq", "qi"] as const; | ||
const list = order.map(prop => { | ||
const v = checkHighestBit(stringToArray(base64urlDecode(jwk[prop]))); | ||
const v = checkHighestBit(stringToArray(base64urlDecode(jwk[prop]!))); | ||
const len = asnEncodeLen(v.length); | ||
@@ -140,2 +130,1 @@ return [0x02].concat(len, v); // int tag is 0x02 | ||
} | ||
import * as assert from 'power-assert'; | ||
import {arrayToPem, pemToArray} from '../src/pkcs1To8'; | ||
import {arrayToString} from '../src/publicSshToPem'; | ||
import { | ||
arrayToPem, | ||
pemToArray, | ||
arrayToString, | ||
lenToArray, | ||
@@ -20,3 +21,3 @@ arrayToLen, | ||
describe('mergeUint8Array', () => { | ||
it('should merge two Uint8Arrays', async () => { | ||
it('should merge two Uint8Arrays', () => { | ||
assert.deepStrictEqual(1, 1); | ||
@@ -72,3 +73,3 @@ }); | ||
describe('all', () => { | ||
it('array to PEM', async () => { | ||
it('array to PEM', () => { | ||
const a = [1, 2, 3]; | ||
@@ -80,14 +81,13 @@ const p = arrayToPem(a); | ||
it('array to String', async () => { | ||
// TODO: any | ||
const a = "ssh-rsa".split("").map(c => (c as any).charCodeAt()); | ||
it('array to String', () => { | ||
const a = "ssh-rsa".split("").map(c => c.charCodeAt(0)); | ||
assert.equal(arrayToString(pemToArray(arrayToPem(a))), "ssh-rsa"); | ||
}); | ||
it('lenToArray', async () => { | ||
it('lenToArray', () => { | ||
const a = 66051; | ||
assert.deepEqual(lenToArray(a), [0, 1, 2, 3]); | ||
}); | ||
}); | ||
it('arrayToLen', async () => { | ||
it('arrayToLen', () => { | ||
const a = [0, 1, 2, 3]; | ||
@@ -158,3 +158,3 @@ assert.deepEqual(arrayToLen(a), 66051); | ||
}); | ||
it("encodePrivateKey", () => { | ||
@@ -161,0 +161,0 @@ encodePrivateKey(jwkPrivate); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
13
48987
28
936