Comparing version 1.1.1 to 1.2.0
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import { KeyObject } from 'crypto'; | ||
import { CertificateRequest } from '../client/fulcio'; | ||
export declare function toCertificateRequest(publicKey: KeyObject, challenge: Buffer): CertificateRequest; | ||
import { SigningCertificateRequest } from '../client/fulcio'; | ||
export declare function toCertificateRequest(identityToken: string, publicKey: KeyObject, challenge: Buffer): SigningCertificateRequest; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toCertificateRequest = void 0; | ||
function toCertificateRequest(publicKey, challenge) { | ||
function toCertificateRequest(identityToken, publicKey, challenge) { | ||
return { | ||
publicKey: { | ||
content: publicKey | ||
.export({ type: 'spki', format: 'der' }) | ||
.toString('base64'), | ||
credentials: { | ||
oidcIdentityToken: identityToken, | ||
}, | ||
signedEmailAddress: challenge.toString('base64'), | ||
publicKeyRequest: { | ||
publicKey: { | ||
algorithm: 'ECDSA', | ||
content: publicKey | ||
.export({ format: 'pem', type: 'spki' }) | ||
.toString('ascii'), | ||
}, | ||
proofOfPossession: challenge.toString('base64'), | ||
}, | ||
}; | ||
} | ||
exports.toCertificateRequest = toCertificateRequest; |
@@ -6,3 +6,2 @@ "use strict"; | ||
const error_1 = require("../error"); | ||
const util_1 = require("../util"); | ||
const format_1 = require("./format"); | ||
@@ -14,6 +13,6 @@ class CAClient { | ||
async createSigningCertificate(identityToken, publicKey, challenge) { | ||
const request = (0, format_1.toCertificateRequest)(publicKey, challenge); | ||
const request = (0, format_1.toCertificateRequest)(identityToken, publicKey, challenge); | ||
try { | ||
const certificate = await this.fulcio.createSigningCertificate(identityToken, request); | ||
return util_1.pem.split(certificate); | ||
const certificate = await this.fulcio.createSigningCertificate(request); | ||
return certificate.signedCertificateEmbeddedSct.chain.certificates; | ||
} | ||
@@ -20,0 +19,0 @@ catch (err) { |
@@ -68,2 +68,3 @@ "use strict"; | ||
oidcIssuer: 'https://oauth2.sigstore.dev/auth', | ||
oidcRedirectURL: process.env.OIDC_REDIRECT_URL, | ||
rekorURL: index_1.sigstore.DEFAULT_REKOR_URL, | ||
@@ -70,0 +71,0 @@ }; |
export interface FulcioOptions { | ||
baseURL: string; | ||
} | ||
export interface CertificateRequest { | ||
publicKey: { | ||
content: string; | ||
export interface SigningCertificateRequest { | ||
credentials: { | ||
oidcIdentityToken: string; | ||
}; | ||
signedEmailAddress: string; | ||
publicKeyRequest: { | ||
publicKey: { | ||
algorithm: string; | ||
content: string; | ||
}; | ||
proofOfPossession: string; | ||
}; | ||
} | ||
export interface SigningCertificateResponse { | ||
signedCertificateEmbeddedSct: { | ||
chain: { | ||
certificates: string[]; | ||
}; | ||
}; | ||
} | ||
/** | ||
@@ -17,3 +30,3 @@ * Fulcio API client. | ||
constructor(options: FulcioOptions); | ||
createSigningCertificate(idToken: string, request: CertificateRequest): Promise<string>; | ||
createSigningCertificate(request: SigningCertificateRequest): Promise<SigningCertificateResponse>; | ||
} |
@@ -34,3 +34,2 @@ "use strict"; | ||
headers: { | ||
Accept: 'application/pem-certificate-chain', | ||
'Content-Type': 'application/json', | ||
@@ -42,11 +41,10 @@ 'User-Agent': util_1.ua.getUserAgent(), | ||
} | ||
async createSigningCertificate(idToken, request) { | ||
const url = `${this.baseUrl}/api/v1/signingCert`; | ||
async createSigningCertificate(request) { | ||
const url = `${this.baseUrl}/api/v2/signingCert`; | ||
const response = await this.fetch(url, { | ||
method: 'POST', | ||
headers: { Authorization: `Bearer ${idToken}` }, | ||
body: JSON.stringify(request), | ||
}); | ||
(0, error_1.checkStatus)(response); | ||
const data = await response.text(); | ||
const data = await response.json(); | ||
return data; | ||
@@ -53,0 +51,0 @@ } |
@@ -11,3 +11,8 @@ import { Provider } from './provider'; | ||
*/ | ||
declare function oauthProvider(issuer: string, clientID: string, clientSecret?: string): Provider; | ||
declare function oauthProvider(options: { | ||
issuer: string; | ||
clientID: string; | ||
clientSecret?: string; | ||
redirectURL?: string; | ||
}): Provider; | ||
/** | ||
@@ -14,0 +19,0 @@ * ciContextProvider returns a new Provider instance which attempts to retrieve |
@@ -30,4 +30,9 @@ "use strict"; | ||
*/ | ||
function oauthProvider(issuer, clientID, clientSecret) { | ||
return new oauth_1.OAuthProvider(new issuer_1.Issuer(issuer), clientID, clientSecret); | ||
function oauthProvider(options) { | ||
return new oauth_1.OAuthProvider({ | ||
issuer: new issuer_1.Issuer(options.issuer), | ||
clientID: options.clientID, | ||
clientSecret: options.clientSecret, | ||
redirectURL: options.redirectURL, | ||
}); | ||
} | ||
@@ -34,0 +39,0 @@ /** |
import { Issuer } from './issuer'; | ||
import { Provider } from './provider'; | ||
interface OAuthProviderOptions { | ||
issuer: Issuer; | ||
clientID: string; | ||
clientSecret?: string; | ||
redirectURL?: string; | ||
} | ||
export declare class OAuthProvider implements Provider { | ||
@@ -10,3 +16,3 @@ private clientID; | ||
private redirectURI?; | ||
constructor(issuer: Issuer, clientID: string, clientSecret?: string); | ||
constructor(options: OAuthProviderOptions); | ||
getToken(): Promise<string>; | ||
@@ -21,1 +27,2 @@ private initiateAuthRequest; | ||
} | ||
export {}; |
@@ -29,6 +29,7 @@ "use strict"; | ||
class OAuthProvider { | ||
constructor(issuer, clientID, clientSecret) { | ||
this.clientID = clientID; | ||
this.clientSecret = clientSecret || ''; | ||
this.issuer = issuer; | ||
constructor(options) { | ||
this.clientID = options.clientID; | ||
this.clientSecret = options.clientSecret || ''; | ||
this.issuer = options.issuer; | ||
this.redirectURI = options.redirectURL; | ||
this.codeVerifier = generateRandomString(32); | ||
@@ -47,5 +48,16 @@ this.state = generateRandomString(16); | ||
const sockets = new Set(); | ||
// Start server and wait till it is listening | ||
// Start server and wait till it is listening. If a redirect URL was | ||
// provided, use that. Otherwise, use a random port and construct the | ||
// redirect URL. | ||
await new Promise((resolve) => { | ||
server.listen(0, resolve); | ||
if (this.redirectURI) { | ||
const url = new url_1.URL(this.redirectURI); | ||
server.listen(Number(url.port), url.hostname, resolve); | ||
} | ||
else { | ||
server.listen(0, resolve); | ||
// Get port the server is listening on and construct the server URL | ||
const port = server.address().port; | ||
this.redirectURI = `http://localhost:${port}`; | ||
} | ||
}); | ||
@@ -59,5 +71,2 @@ // Keep track of connections to the server so we can force a shutdown | ||
}); | ||
// Get port the server is listening on and construct the server URL | ||
const port = server.address().port; | ||
this.redirectURI = `http://localhost:${port}`; | ||
const result = new Promise((resolve, reject) => { | ||
@@ -64,0 +73,0 @@ // Set-up handler for post-auth redirect |
@@ -21,2 +21,3 @@ /// <reference types="node" /> | ||
oidcClientSecret?: string; | ||
oidcRedirectURL?: string; | ||
} & TLogOptions; | ||
@@ -23,0 +24,0 @@ export type VerifyOptions = { |
@@ -118,3 +118,8 @@ "use strict"; | ||
if (options.oidcIssuer && options.oidcClientID) { | ||
idps.push(identity_1.default.oauthProvider(options.oidcIssuer, options.oidcClientID, options.oidcClientSecret)); | ||
idps.push(identity_1.default.oauthProvider({ | ||
issuer: options.oidcIssuer, | ||
clientID: options.oidcClientID, | ||
clientSecret: options.oidcClientSecret, | ||
redirectURL: options.oidcRedirectURL, | ||
})); | ||
} | ||
@@ -121,0 +126,0 @@ } |
/// <reference types="node" /> | ||
export declare function split(certificate: string): string[]; | ||
export declare function toDER(certificate: string): Buffer; | ||
export declare function fromDER(certificate: Buffer, type?: string): string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.fromDER = exports.toDER = exports.split = void 0; | ||
exports.fromDER = exports.toDER = void 0; | ||
/* | ||
@@ -21,23 +21,2 @@ Copyright 2022 The Sigstore Authors. | ||
const PEM_FOOTER = /-----END (.*)-----/; | ||
// Given a set of PEM-encoded certificates bundled in a single string, returns | ||
// an array of certificates. Standard PEM encoding dictates that each certificate | ||
// should have a trailing newline after the footer. | ||
function split(certificate) { | ||
const certs = []; | ||
let cert = []; | ||
certificate.split('\n').forEach((line) => { | ||
line.includes; | ||
if (line.match(PEM_HEADER)) { | ||
cert = []; | ||
} | ||
if (line.length > 0) { | ||
cert.push(line); | ||
} | ||
if (line.match(PEM_FOOTER)) { | ||
certs.push(cert.join('\n').concat('\n')); | ||
} | ||
}); | ||
return certs; | ||
} | ||
exports.split = split; | ||
function toDER(certificate) { | ||
@@ -44,0 +23,0 @@ let der = ''; |
@@ -115,3 +115,3 @@ "use strict"; | ||
} | ||
ByteStream.BLOCK_SIZE = 1024; | ||
exports.ByteStream = ByteStream; | ||
ByteStream.BLOCK_SIZE = 1024; |
@@ -6,8 +6,5 @@ /// <reference types="node" /> | ||
readonly subs: ASN1Obj[]; | ||
private buf; | ||
private headerLength; | ||
constructor(tag: ASN1Tag, headerLength: number, buf: Buffer, subs: ASN1Obj[]); | ||
readonly value: Buffer; | ||
constructor(tag: ASN1Tag, value: Buffer, subs: ASN1Obj[]); | ||
static parseBuffer(buf: Buffer): ASN1Obj; | ||
get value(): Buffer; | ||
get raw(): Buffer; | ||
toDER(): Buffer; | ||
@@ -14,0 +11,0 @@ toBoolean(): boolean; |
@@ -25,6 +25,5 @@ "use strict"; | ||
class ASN1Obj { | ||
constructor(tag, headerLength, buf, subs) { | ||
constructor(tag, value, subs) { | ||
this.tag = tag; | ||
this.headerLength = headerLength; | ||
this.buf = buf; | ||
this.value = value; | ||
this.subs = subs; | ||
@@ -36,14 +35,2 @@ } | ||
} | ||
// Returns the raw bytes of the ASN.1 object's value. For constructed objects, | ||
// this is the concatenation of the raw bytes of the values of its children. | ||
// For primitive objects, this is the raw bytes of the object's value. | ||
// Use the various to* methods to parse the value into a specific type. | ||
get value() { | ||
return this.buf.subarray(this.headerLength); | ||
} | ||
// Returns the raw bytes of the entire ASN.1 object (including tag, length, | ||
// and value) | ||
get raw() { | ||
return this.buf; | ||
} | ||
toDER() { | ||
@@ -119,9 +106,7 @@ const valueStream = new stream_1.ByteStream(); | ||
function parseStream(stream) { | ||
// Capture current stream position so we know where this object starts | ||
const startPos = stream.position; | ||
// Parse tag and length from stream | ||
// Parse tag, length, and value from stream | ||
const tag = new tag_1.ASN1Tag(stream.getUint8()); | ||
const len = (0, length_1.decodeLength)(stream); | ||
// Calculate length of header (tag + length) | ||
const header = stream.position - startPos; | ||
const value = stream.slice(stream.position, len); | ||
const start = stream.position; | ||
let subs = []; | ||
@@ -146,7 +131,5 @@ // If the object is constructed, parse its children. Sometimes, children | ||
if (subs.length === 0) { | ||
stream.seek(startPos + header + len); | ||
stream.seek(start + len); | ||
} | ||
// Capture the raw bytes of the object (including tag, length, and value) | ||
const buf = stream.slice(startPos, header + len); | ||
return new ASN1Obj(tag, header, buf, subs); | ||
return new ASN1Obj(tag, value, subs); | ||
} | ||
@@ -153,0 +136,0 @@ function collectSubs(stream, len) { |
@@ -62,3 +62,3 @@ "use strict"; | ||
get publicKey() { | ||
return this.subjectPublicKeyInfoObj.raw; | ||
return this.subjectPublicKeyInfoObj.toDER(); | ||
} | ||
@@ -119,3 +119,3 @@ get signatureAlgorithm() { | ||
const key = util_1.crypto.createPublicKey(publicKey); | ||
return util_1.crypto.verifyBlob(this.tbsCertificate.raw, key, this.signatureValue, this.signatureAlgorithm); | ||
return util_1.crypto.verifyBlob(this.tbsCertificate.toDER(), key, this.signatureValue, this.signatureAlgorithm); | ||
} | ||
@@ -126,3 +126,3 @@ validForDate(date) { | ||
equals(other) { | ||
return this.root.raw.equals(other.root.raw); | ||
return this.root.toDER().equals(other.root.toDER()); | ||
} | ||
@@ -173,4 +173,5 @@ verifySCTs(issuer, logs) { | ||
clone() { | ||
const clone = Buffer.alloc(this.root.raw.length); | ||
this.root.raw.copy(clone); | ||
const der = this.root.toDER(); | ||
const clone = Buffer.alloc(der.length); | ||
der.copy(clone); | ||
return x509Certificate.parse(clone); | ||
@@ -177,0 +178,0 @@ } |
{ | ||
"name": "sigstore", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "code-signing for npm packages", | ||
@@ -54,3 +54,3 @@ "main": "dist/index.js", | ||
"ts-jest": "^29.0.5", | ||
"typescript": "^4.7.2" | ||
"typescript": "^5.0.2" | ||
}, | ||
@@ -57,0 +57,0 @@ "dependencies": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5296
231816
11