-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: use forge partially to generate certificates #6325
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// simplified fork of | ||
// https://github.com/jfromaniello/selfsigned/blob/da38146f8d02183c35f49f91659a744a243e8707/index.js | ||
// with inlined options and partial node-forge usage | ||
// to achieve smaller bundle | ||
// | ||
// this utility create untrusted certificate which still | ||
// allows to access page after proceeding a wall with warning | ||
// | ||
// should be deprecated eventually and replaced with recipes | ||
// about generating secure trusted certificates | ||
|
||
// @ts-ignore | ||
import forge from 'node-forge/lib/forge' | ||
// @ts-ignore | ||
import 'node-forge/lib/pki' | ||
|
||
// a hexString is considered negative if it's most significant bit is 1 | ||
// because serial numbers use ones' complement notation | ||
// this RFC in section 4.1.2.2 requires serial numbers to be positive | ||
// http://www.ietf.org/rfc/rfc5280.txt | ||
function toPositiveHex(hexString: string) { | ||
let mostSiginficativeHexAsInt = parseInt(hexString[0], 16) | ||
if (mostSiginficativeHexAsInt < 8) { | ||
return hexString | ||
} | ||
|
||
mostSiginficativeHexAsInt -= 8 | ||
return mostSiginficativeHexAsInt.toString() + hexString.substring(1) | ||
} | ||
|
||
export function createCertificate(): string { | ||
const days = 30 | ||
const keySize = 2048 | ||
|
||
const extensions = [ | ||
// { | ||
// name: 'basicConstraints', | ||
// cA: true, | ||
// }, | ||
{ | ||
name: 'keyUsage', | ||
keyCertSign: true, | ||
digitalSignature: true, | ||
nonRepudiation: true, | ||
keyEncipherment: true, | ||
dataEncipherment: true | ||
}, | ||
{ | ||
name: 'extKeyUsage', | ||
serverAuth: true, | ||
clientAuth: true, | ||
codeSigning: true, | ||
timeStamping: true | ||
}, | ||
{ | ||
name: 'subjectAltName', | ||
altNames: [ | ||
{ | ||
// type 2 is DNS | ||
type: 2, | ||
value: 'localhost' | ||
}, | ||
{ | ||
type: 2, | ||
value: 'localhost.localdomain' | ||
}, | ||
{ | ||
type: 2, | ||
value: 'lvh.me' | ||
}, | ||
{ | ||
type: 2, | ||
value: '*.lvh.me' | ||
}, | ||
{ | ||
type: 2, | ||
value: '[::1]' | ||
}, | ||
{ | ||
// type 7 is IP | ||
type: 7, | ||
ip: '127.0.0.1' | ||
}, | ||
{ | ||
type: 7, | ||
ip: 'fe80::1' | ||
} | ||
] | ||
} | ||
] | ||
|
||
const attrs = [ | ||
{ | ||
name: 'commonName', | ||
value: 'example.org' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the CN should match the subject alternative name, browser will complain There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should do another PR afterwards to improve these things? Lets review only the change away from selfsigned in this one and you can send the next one on top of it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is selfsigned default. Do we need to change anything? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I know this will be deprecated but if included add something functional, 30 days is too short, and from the logic perspective the work to be done to include 2 years doesn't matter (we are not changing the key lengths from 2048 to 4096 bits). The SSL/TLS certificates on browsers are quite sensitive... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @userquin could you check the PR against the current implementation? I think we have the same values. Lets try to merge this one and I think we can better discuss changes to the params in a future PR (hopefully from you :) ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @patak-dev ok, no problem, I'm creating the p12 to import on windows and preparing some test.. |
||
}, | ||
{ | ||
name: 'countryName', | ||
value: 'US' | ||
}, | ||
{ | ||
shortName: 'ST', | ||
value: 'Virginia' | ||
}, | ||
{ | ||
name: 'localityName', | ||
value: 'Blacksburg' | ||
}, | ||
{ | ||
name: 'organizationName', | ||
value: 'Test' | ||
}, | ||
{ | ||
shortName: 'OU', | ||
value: 'Test' | ||
} | ||
] | ||
|
||
const keyPair = forge.pki.rsa.generateKeyPair(keySize) | ||
|
||
const cert = forge.pki.createCertificate() | ||
|
||
cert.serialNumber = toPositiveHex( | ||
forge.util.bytesToHex(forge.random.getBytesSync(9)) | ||
) // the serial number can be decimal or hex (if preceded by 0x) | ||
|
||
cert.validity.notBefore = new Date() | ||
cert.validity.notAfter = new Date() | ||
cert.validity.notAfter.setDate(cert.validity.notBefore.getDate() + days) | ||
|
||
cert.setSubject(attrs) | ||
cert.setIssuer(attrs) | ||
|
||
cert.publicKey = keyPair.publicKey | ||
|
||
cert.setExtensions(extensions) | ||
|
||
const algorithm = forge.md.sha256.create() | ||
cert.sign(keyPair.privateKey, algorithm) | ||
|
||
const privateKeyPem = forge.pki.privateKeyToPem(keyPair.privateKey) | ||
const certPem = forge.pki.certificateToPem(cert) | ||
|
||
return privateKeyPem + certPem | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add more days, the limit is too short, I configure the ssl/tls certificates with 2 years
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what we have with existing logic. I think it's ok to keep as is if we are gonna deprecate and remove this feature eventually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TrySound can you provide a certificate generated with the code here?, my email is [email protected]