New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@expo/code-signing-certificates

Package Overview
Dependencies
Maintainers
23
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@expo/code-signing-certificates - npm Package Compare versions

Comparing version

to
0.0.2

47

build/__tests__/main-test.js

@@ -74,3 +74,3 @@ "use strict";

// check self-signed
expect(certificate.issuer.hash).toEqual(certificate.subject.hash);
expect(certificate.verify(certificate)).toBe(true);
// check extensions

@@ -223,2 +223,47 @@ expect(certificate.getExtension('keyUsage')).toMatchObject({

});
describe('CSR generation and certificate generation from CA + CSR', () => {
it('generates a development certificate', async () => {
const [issuerPrivateKeyPEM, issuerCertificatePEM] = await Promise.all([
fs_1.promises.readFile(path_1.default.join(__dirname, './fixtures/test-private-key.pem'), 'utf8'),
fs_1.promises.readFile(path_1.default.join(__dirname, './fixtures/test-certificate.pem'), 'utf8'),
]);
const issuerPrivateKey = (0, main_1.convertPrivateKeyPEMToPrivateKey)(issuerPrivateKeyPEM);
const issuerCertificate = (0, main_1.convertCertificatePEMToCertificate)(issuerCertificatePEM);
const keyPair = (0, main_1.generateKeyPair)();
const csr1 = (0, main_1.generateCSR)(keyPair, 'Test common name');
const csrPEM = (0, main_1.convertCSRToCSRPEM)(csr1);
const csr = (0, main_1.convertCSRPEMToCSR)(csrPEM);
const certificate = (0, main_1.generateDevelopmentCertificateFromCSR)(issuerPrivateKey, issuerCertificate, csr, 'testApp', 'testScopeKey');
// check signed by issuer
expect(issuerCertificate.verify(certificate)).toBe(true);
// check subject attributes are transferred
expect(certificate.subject.getField('CN').value).toEqual('Test common name');
// check extensions
expect(certificate.getExtension('keyUsage')).toMatchObject({
critical: true,
dataEncipherment: false,
digitalSignature: true,
id: '2.5.29.15',
keyCertSign: false,
keyEncipherment: false,
name: 'keyUsage',
nonRepudiation: false,
});
expect(certificate.getExtension('extKeyUsage')).toMatchObject({
clientAuth: false,
codeSigning: true,
critical: true,
emailProtection: false,
id: '2.5.29.37',
name: 'extKeyUsage',
serverAuth: false,
timeStamping: false,
});
expect(certificate.getExtension('expoProjectInformation')).toMatchObject({
name: 'expoProjectInformation',
id: main_1.expoProjectInformationOID,
value: 'testApp,testScopeKey',
});
});
});
//# sourceMappingURL=main-test.js.map
import { pki as PKI } from 'node-forge';
export declare const expoProjectInformationOID = "1.2.840.113556.1.8000.2554.43437.254.128.102.157.7894389.20439.2.1";
/**

@@ -50,2 +51,14 @@ * Generate a public and private RSA key pair.

export declare function convertCertificatePEMToCertificate(certificatePEM: string): PKI.Certificate;
/**
* Convert a CSR to PEM-formatted X.509 CSR
* @param csr CSR
* @returns X.509 CSR
*/
export declare function convertCSRToCSRPEM(csr: PKI.CertificateRequest): string;
/**
* Convert a PEM-formatted X.509 CSR to a CSR
* @param CSRPEM PEM-formatted X.509 CSR
* @returns CSR
*/
export declare function convertCSRPEMToCSR(CSRPEM: string): PKI.CertificateRequest;
declare type GenerateParameters = {

@@ -93,2 +106,25 @@ /**

export declare function signStringRSASHA256AndVerify(privateKey: PKI.rsa.PrivateKey, certificate: PKI.Certificate, stringToSign: string): string;
/**
* Generate a self-signed CSR for a given key pair. Most commonly used with {@link generateDevelopmentCertificateFromCSR}.
* @param keyPair RSA key pair
* @param commonName commonName attribute of the subject of the resulting certificate (human readable name of the certificate)
* @returns CSR
*/
export declare function generateCSR(keyPair: PKI.rsa.KeyPair, commonName: string): PKI.CertificateRequest;
/**
* For use by a server to generate a development certificate (good for 30 days) for a particular
* appId and scopeKey (fields verified by the client during certificate validation).
*
* Note that this function assumes the issuer is trusted, and that the user that created the CSR and issued
* the request has permission to sign manifests for the appId and scopeKey. This constraint must be
* verified on the server before calling this method.
*
* @param issuerPrivateKey private key to sign the resulting certificate with
* @param issuerCertificate parent certificate (should be a CA) of the resulting certificate
* @param csr certificate signing request containing the user's public key
* @param appId app ID (UUID) of the app that the resulting certificate will sign the development manifest for
* @param scopeKey scope key of the app that the resuting certificate will sign the development manifest for
* @returns certificate to use to sign development manifests
*/
export declare function generateDevelopmentCertificateFromCSR(issuerPrivateKey: PKI.rsa.PrivateKey, issuerCertificate: PKI.Certificate, csr: PKI.CertificateRequest, appId: string, scopeKey: string): PKI.Certificate;
export {};

@@ -6,6 +6,8 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.signStringRSASHA256AndVerify = exports.validateSelfSignedCertificate = exports.generateSelfSignedCodeSigningCertificate = exports.convertCertificatePEMToCertificate = exports.convertPrivateKeyPEMToPrivateKey = exports.convertPublicKeyPEMToPublicKey = exports.convertKeyPairPEMToKeyPair = exports.convertCertificateToCertificatePEM = exports.convertKeyPairToPEM = exports.generateKeyPair = void 0;
exports.generateDevelopmentCertificateFromCSR = exports.generateCSR = exports.signStringRSASHA256AndVerify = exports.validateSelfSignedCertificate = exports.generateSelfSignedCodeSigningCertificate = exports.convertCSRPEMToCSR = exports.convertCSRToCSRPEM = exports.convertCertificatePEMToCertificate = exports.convertPrivateKeyPEMToPrivateKey = exports.convertPublicKeyPEMToPublicKey = exports.convertKeyPairPEMToKeyPair = exports.convertCertificateToCertificatePEM = exports.convertKeyPairToPEM = exports.generateKeyPair = exports.expoProjectInformationOID = void 0;
const assert_1 = __importDefault(require("assert"));
const node_forge_1 = require("node-forge");
const utils_1 = require("./utils");
// generated with oidgen script. in the microsoft OID space. could apply for Expo space but would take time: https://pen.iana.org/pen/PenApplication.page
exports.expoProjectInformationOID = '1.2.840.113556.1.8000.2554.43437.254.128.102.157.7894389.20439.2.1';
/**

@@ -77,6 +79,24 @@ * Generate a public and private RSA key pair.

function convertCertificatePEMToCertificate(certificatePEM) {
return node_forge_1.pki.certificateFromPem(certificatePEM);
return node_forge_1.pki.certificateFromPem(certificatePEM, true);
}
exports.convertCertificatePEMToCertificate = convertCertificatePEMToCertificate;
/**
* Convert a CSR to PEM-formatted X.509 CSR
* @param csr CSR
* @returns X.509 CSR
*/
function convertCSRToCSRPEM(csr) {
return node_forge_1.pki.certificationRequestToPem(csr);
}
exports.convertCSRToCSRPEM = convertCSRToCSRPEM;
/**
* Convert a PEM-formatted X.509 CSR to a CSR
* @param CSRPEM PEM-formatted X.509 CSR
* @returns CSR
*/
function convertCSRPEMToCSR(CSRPEM) {
return node_forge_1.pki.certificationRequestFromPem(CSRPEM, true);
}
exports.convertCSRPEMToCSR = convertCSRPEMToCSR;
/**
* Generate a self-signed code-signing certificate for use with expo-updates.

@@ -187,2 +207,79 @@ * Note that while certificate chains may be supported at some point in expo-updates, for now

exports.signStringRSASHA256AndVerify = signStringRSASHA256AndVerify;
/**
* Generate a self-signed CSR for a given key pair. Most commonly used with {@link generateDevelopmentCertificateFromCSR}.
* @param keyPair RSA key pair
* @param commonName commonName attribute of the subject of the resulting certificate (human readable name of the certificate)
* @returns CSR
*/
function generateCSR(keyPair, commonName) {
const csr = node_forge_1.pki.createCertificationRequest();
csr.publicKey = keyPair.publicKey;
const attrs = [
{
name: 'commonName',
value: commonName,
},
];
csr.setSubject(attrs);
csr.sign(keyPair.privateKey, node_forge_1.md.sha256.create());
return csr;
}
exports.generateCSR = generateCSR;
/**
* For use by a server to generate a development certificate (good for 30 days) for a particular
* appId and scopeKey (fields verified by the client during certificate validation).
*
* Note that this function assumes the issuer is trusted, and that the user that created the CSR and issued
* the request has permission to sign manifests for the appId and scopeKey. This constraint must be
* verified on the server before calling this method.
*
* @param issuerPrivateKey private key to sign the resulting certificate with
* @param issuerCertificate parent certificate (should be a CA) of the resulting certificate
* @param csr certificate signing request containing the user's public key
* @param appId app ID (UUID) of the app that the resulting certificate will sign the development manifest for
* @param scopeKey scope key of the app that the resuting certificate will sign the development manifest for
* @returns certificate to use to sign development manifests
*/
function generateDevelopmentCertificateFromCSR(issuerPrivateKey, issuerCertificate, csr, appId, scopeKey) {
(0, assert_1.default)(csr.verify(csr), 'CSR not self-signed');
const certificate = node_forge_1.pki.createCertificate();
certificate.publicKey = csr.publicKey;
certificate.serialNumber = (0, utils_1.toPositiveHex)(node_forge_1.util.bytesToHex(node_forge_1.random.getBytesSync(9)));
// set certificate subject attrs from CSR
certificate.setSubject(csr.subject.attributes);
// 30 day validity
certificate.validity.notBefore = new Date();
certificate.validity.notAfter = new Date();
certificate.validity.notAfter.setDate(certificate.validity.notBefore.getDate() + 30);
certificate.setIssuer(issuerCertificate.subject.attributes);
certificate.setExtensions([
{
name: 'keyUsage',
critical: true,
keyCertSign: false,
digitalSignature: true,
nonRepudiation: false,
keyEncipherment: false,
dataEncipherment: false,
},
{
name: 'extKeyUsage',
critical: true,
serverAuth: false,
clientAuth: false,
codeSigning: true,
emailProtection: false,
timeStamping: false,
},
{
name: 'expoProjectInformation',
id: exports.expoProjectInformationOID,
// critical: true, // can't be critical since openssl verify doesn't know about this extension
value: `${appId},${scopeKey}`,
},
]);
certificate.sign(issuerPrivateKey, node_forge_1.md.sha256.create());
return certificate;
}
exports.generateDevelopmentCertificateFromCSR = generateDevelopmentCertificateFromCSR;
//# sourceMappingURL=main.js.map

14

package.json
{
"name": "@expo/code-signing-certificates",
"version": "0.0.1",
"version": "0.0.2",
"description": "A library for working with expo-updates code signing certificates",

@@ -12,3 +12,7 @@ "main": "build/main.js",

"lint-fix": "eslint src --fix",
"test": "jest --rootDir . --config jest.config.js"
"test": "jest --rootDir . --config jest.config.js",
"generate-example-certificates": "ts-node -r tsconfig-paths/register --project tsconfig.scripts.json ./scripts/generateExampleCertificates.ts",
"generate-example-self-signed": "ts-node -r tsconfig-paths/register --project tsconfig.scripts.json ./scripts/generateExampleSelfSignedCertificate.ts",
"oidgen": "ts-node -r tsconfig-paths/register --project tsconfig.scripts.json ./scripts/oidgen/oidgen.ts",
"sign-manifest-for-testing": "ts-node -r tsconfig-paths/register --project tsconfig.scripts.json ./scripts/signManifestForTesting.ts"
},

@@ -36,5 +40,7 @@ "repository": {

"devDependencies": {
"@tsconfig/node14": "^1.0.1",
"@types/jest": "^27.4.0",
"@types/jsbn": "^1.2.30",
"@types/node-forge": "^1.0.0",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.11.0",

@@ -47,4 +53,6 @@ "@typescript-eslint/parser": "^5.11.0",

"ts-jest": "^27.1.3",
"typescript": "^4.5.5"
"ts-node-dev": "^1.1.8",
"typescript": "^4.5.5",
"uuid": "^8.3.2"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet