Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fae568887 | ||
|
|
38bcf9b1c5 | ||
|
|
f03e04cc3f | ||
|
|
3fd15bdad4 | ||
|
|
f642f6cafe | ||
|
|
67164a6c7a | ||
|
|
e6c7a2a1f2 | ||
|
|
d8029d4690 | ||
|
|
bfa7e6911b | ||
|
|
d94b522220 |
@@ -1,4 +0,0 @@
|
|||||||
lib/
|
|
||||||
dist/
|
|
||||||
node_modules/
|
|
||||||
coverage/
|
|
||||||
84
.github/linters/.eslintrc.yml
vendored
84
.github/linters/.eslintrc.yml
vendored
@@ -1,84 +0,0 @@
|
|||||||
env:
|
|
||||||
node: true
|
|
||||||
es6: true
|
|
||||||
jest: true
|
|
||||||
|
|
||||||
globals:
|
|
||||||
Atomics: readonly
|
|
||||||
SharedArrayBuffer: readonly
|
|
||||||
|
|
||||||
ignorePatterns:
|
|
||||||
- '!.*'
|
|
||||||
- '**/node_modules/.*'
|
|
||||||
- '**/dist/.*'
|
|
||||||
- '**/coverage/.*'
|
|
||||||
- '*.json'
|
|
||||||
|
|
||||||
parser: '@typescript-eslint/parser'
|
|
||||||
|
|
||||||
parserOptions:
|
|
||||||
ecmaVersion: 2023
|
|
||||||
sourceType: module
|
|
||||||
project:
|
|
||||||
- './.github/linters/tsconfig.json'
|
|
||||||
- './tsconfig.json'
|
|
||||||
|
|
||||||
plugins:
|
|
||||||
- jest
|
|
||||||
- '@typescript-eslint'
|
|
||||||
|
|
||||||
extends:
|
|
||||||
- eslint:recommended
|
|
||||||
- plugin:@typescript-eslint/eslint-recommended
|
|
||||||
- plugin:@typescript-eslint/recommended
|
|
||||||
- plugin:github/recommended
|
|
||||||
- plugin:jest/recommended
|
|
||||||
|
|
||||||
rules:
|
|
||||||
{
|
|
||||||
'camelcase': 'off',
|
|
||||||
'eslint-comments/no-use': 'off',
|
|
||||||
'eslint-comments/no-unused-disable': 'off',
|
|
||||||
'i18n-text/no-en': 'off',
|
|
||||||
'import/no-namespace': 'off',
|
|
||||||
'import/no-unresolved': ['error', { 'ignore': ['csv-parse/sync'] }],
|
|
||||||
'no-console': 'off',
|
|
||||||
'no-unused-vars': 'off',
|
|
||||||
'prettier/prettier': 'error',
|
|
||||||
'semi': 'off',
|
|
||||||
'@typescript-eslint/array-type': 'error',
|
|
||||||
'@typescript-eslint/await-thenable': 'error',
|
|
||||||
'@typescript-eslint/ban-ts-comment': 'error',
|
|
||||||
'@typescript-eslint/consistent-type-assertions': 'error',
|
|
||||||
'@typescript-eslint/explicit-member-accessibility':
|
|
||||||
['error', { 'accessibility': 'no-public' }],
|
|
||||||
'@typescript-eslint/explicit-function-return-type':
|
|
||||||
['error', { 'allowExpressions': true }],
|
|
||||||
'@typescript-eslint/func-call-spacing': ['error', 'never'],
|
|
||||||
'@typescript-eslint/no-array-constructor': 'error',
|
|
||||||
'@typescript-eslint/no-empty-interface': 'error',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'error',
|
|
||||||
'@typescript-eslint/no-extraneous-class': 'error',
|
|
||||||
'@typescript-eslint/no-for-in-array': 'error',
|
|
||||||
'@typescript-eslint/no-inferrable-types': 'error',
|
|
||||||
'@typescript-eslint/no-misused-new': 'error',
|
|
||||||
'@typescript-eslint/no-namespace': 'error',
|
|
||||||
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
||||||
'@typescript-eslint/no-require-imports': 'error',
|
|
||||||
'@typescript-eslint/no-unnecessary-qualifier': 'error',
|
|
||||||
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
|
||||||
'@typescript-eslint/no-unused-vars': 'error',
|
|
||||||
'@typescript-eslint/no-useless-constructor': 'error',
|
|
||||||
'@typescript-eslint/no-var-requires': 'error',
|
|
||||||
'@typescript-eslint/prefer-for-of': 'warn',
|
|
||||||
'@typescript-eslint/prefer-function-type': 'warn',
|
|
||||||
'@typescript-eslint/prefer-includes': 'error',
|
|
||||||
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
|
|
||||||
'@typescript-eslint/promise-function-async': 'error',
|
|
||||||
'@typescript-eslint/require-array-sort-compare': 'error',
|
|
||||||
'@typescript-eslint/restrict-plus-operands': 'error',
|
|
||||||
'@typescript-eslint/semi': ['error', 'never'],
|
|
||||||
'@typescript-eslint/space-before-function-paren': 'off',
|
|
||||||
'@typescript-eslint/type-annotation-spacing': 'error',
|
|
||||||
'@typescript-eslint/unbound-method': 'error'
|
|
||||||
}
|
|
||||||
93
.github/linters/eslint.config.mjs
vendored
Normal file
93
.github/linters/eslint.config.mjs
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import eslint from '@eslint/js'
|
||||||
|
import importplugin from 'eslint-plugin-import'
|
||||||
|
import jestplugin from 'eslint-plugin-jest'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
|
||||||
|
export default tseslint.config(
|
||||||
|
// Ignore non-project files
|
||||||
|
{
|
||||||
|
name: 'ignore',
|
||||||
|
ignores: ['.github', 'dist', 'coverage', '**/*.json', 'jest.setup.js']
|
||||||
|
},
|
||||||
|
// Use recommended rules from ESLint, TypeScript, and other plugins
|
||||||
|
eslint.configs.recommended,
|
||||||
|
tseslint.configs.recommendedTypeChecked,
|
||||||
|
jestplugin.configs['flat/recommended'],
|
||||||
|
importplugin.flatConfigs.recommended,
|
||||||
|
importplugin.flatConfigs.typescript,
|
||||||
|
// Override some rules
|
||||||
|
{
|
||||||
|
name: 'project-settings',
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2023,
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./.github/linters/tsconfig.json', './tsconfig.json']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// eslint rules
|
||||||
|
eqeqeq: ['error', 'smart'],
|
||||||
|
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
|
||||||
|
'no-console': 'off',
|
||||||
|
'no-implicit-globals': 'error',
|
||||||
|
'no-inner-declarations': 'error',
|
||||||
|
'no-invalid-this': 'error',
|
||||||
|
'no-return-assign': 'error',
|
||||||
|
'no-sequences': 'error',
|
||||||
|
'no-shadow': 'error',
|
||||||
|
'no-useless-concat': 'error',
|
||||||
|
'object-shorthand': ['error', 'always', { avoidQuotes: true }],
|
||||||
|
'one-var': ['error', 'never'],
|
||||||
|
'prefer-template': 'error',
|
||||||
|
|
||||||
|
// typescript-eslint rules
|
||||||
|
'@typescript-eslint/array-type': 'error',
|
||||||
|
'@typescript-eslint/consistent-type-assertions': 'error',
|
||||||
|
'@typescript-eslint/explicit-function-return-type': [
|
||||||
|
'error',
|
||||||
|
{ allowExpressions: true }
|
||||||
|
],
|
||||||
|
'@typescript-eslint/explicit-member-accessibility': [
|
||||||
|
'error',
|
||||||
|
{ accessibility: 'no-public' }
|
||||||
|
],
|
||||||
|
'@typescript-eslint/no-extraneous-class': 'error',
|
||||||
|
'@typescript-eslint/no-inferrable-types': 'error',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'warn',
|
||||||
|
'@typescript-eslint/no-unnecessary-qualifier': 'error',
|
||||||
|
'@typescript-eslint/no-unsafe-argument': 'off',
|
||||||
|
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||||
|
'@typescript-eslint/no-useless-constructor': 'error',
|
||||||
|
'@typescript-eslint/prefer-for-of': 'warn',
|
||||||
|
'@typescript-eslint/prefer-function-type': 'warn',
|
||||||
|
'@typescript-eslint/prefer-includes': 'error',
|
||||||
|
'@typescript-eslint/prefer-string-starts-ends-with': 'error',
|
||||||
|
'@typescript-eslint/promise-function-async': 'error',
|
||||||
|
'@typescript-eslint/require-array-sort-compare': 'error',
|
||||||
|
'@typescript-eslint/restrict-template-expressions': 'off',
|
||||||
|
|
||||||
|
// eslint-plugin-import rules
|
||||||
|
'import/extensions': 'error',
|
||||||
|
'import/first': 'error',
|
||||||
|
'import/no-absolute-path': 'error',
|
||||||
|
'import/no-commonjs': 'error',
|
||||||
|
'import/no-deprecated': 'warn',
|
||||||
|
'import/no-dynamic-require': 'error',
|
||||||
|
'import/no-extraneous-dependencies': 'error',
|
||||||
|
'import/no-mutable-exports': 'error',
|
||||||
|
'import/no-namespace': 'off',
|
||||||
|
'import/no-unresolved': ['error', { ignore: ['csv-parse/sync'] }],
|
||||||
|
'import/no-anonymous-default-export': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
allowAnonymousClass: false,
|
||||||
|
allowAnonymousFunction: false,
|
||||||
|
allowArray: true,
|
||||||
|
allowArrowFunction: false,
|
||||||
|
allowLiteral: true,
|
||||||
|
allowObject: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
56
README.md
56
README.md
@@ -74,20 +74,25 @@ See [action.yml](action.yml)
|
|||||||
- uses: actions/attest@v2
|
- uses: actions/attest@v2
|
||||||
with:
|
with:
|
||||||
# Path to the artifact serving as the subject of the attestation. Must
|
# Path to the artifact serving as the subject of the attestation. Must
|
||||||
# specify exactly one of "subject-path" or "subject-digest". May contain
|
# specify exactly one of "subject-path", "subject-digest", or
|
||||||
# a glob pattern or list of paths (total subject count cannot exceed 1024).
|
# "subject-checksums". May contain a glob pattern or list of paths
|
||||||
|
# (total subject count cannot exceed 1024).
|
||||||
subject-path:
|
subject-path:
|
||||||
|
|
||||||
# SHA256 digest of the subject for the attestation. Must be in the form
|
# SHA256 digest of the subject for the attestation. Must be in the form
|
||||||
# "sha256:hex_digest" (e.g. "sha256:abc123..."). Must specify exactly one
|
# "sha256:hex_digest" (e.g. "sha256:abc123..."). Must specify exactly one
|
||||||
# of "subject-path" or "subject-digest".
|
# of "subject-path", "subject-digest", or "subject-checksums".
|
||||||
subject-digest:
|
subject-digest:
|
||||||
|
|
||||||
# Subject name as it should appear in the attestation. Required unless
|
# Subject name as it should appear in the attestation. Required when
|
||||||
# "subject-path" is specified, in which case it will be inferred from the
|
# identifying the subject with the "subject-digest" input.
|
||||||
# path.
|
|
||||||
subject-name:
|
subject-name:
|
||||||
|
|
||||||
|
# Path to checksums file containing digest and name of subjects for
|
||||||
|
# attestation. Must specify exactly one of "subject-path", "subject-digest",
|
||||||
|
# or "subject-checksums".
|
||||||
|
subject-checksums:
|
||||||
|
|
||||||
# URI identifying the type of the predicate.
|
# URI identifying the type of the predicate.
|
||||||
predicate-type:
|
predicate-type:
|
||||||
|
|
||||||
@@ -122,7 +127,7 @@ See [action.yml](action.yml)
|
|||||||
| Name | Description | Example |
|
| Name | Description | Example |
|
||||||
| ----------------- | -------------------------------------------------------------- | ------------------------------------------------ |
|
| ----------------- | -------------------------------------------------------------- | ------------------------------------------------ |
|
||||||
| `attestation-id` | GitHub ID for the attestation | `123456` |
|
| `attestation-id` | GitHub ID for the attestation | `123456` |
|
||||||
| `attestation-url` | Absolute path to the file containing the generated attestation | `https://github.com/foo/bar/attestations/123456` |
|
| `attestation-url` | URL for the attestation summary | `https://github.com/foo/bar/attestations/123456` |
|
||||||
| `bundle-path` | Absolute path to the file containing the generated attestation | `/tmp/attestation.json` |
|
| `bundle-path` | Absolute path to the file containing the generated attestation | `/tmp/attestation.json` |
|
||||||
|
|
||||||
<!-- markdownlint-enable MD013 -->
|
<!-- markdownlint-enable MD013 -->
|
||||||
@@ -209,6 +214,43 @@ newline delimited list:
|
|||||||
dist/bar
|
dist/bar
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Identify Subjects with Checksums File
|
||||||
|
|
||||||
|
If you are using tools like
|
||||||
|
[goreleaser](https://goreleaser.com/customization/checksum/) or
|
||||||
|
[jreleaser](https://jreleaser.org/guide/latest/reference/checksum.html) which
|
||||||
|
generate a checksums file you can identify the attestation subjects by passing
|
||||||
|
the path of the checksums file to the `subject-checksums` input. Each of the
|
||||||
|
artifacts identified in the checksums file will be listed as a subject for the
|
||||||
|
attestation.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Calculate artifact digests
|
||||||
|
run: |
|
||||||
|
shasum -a 256 foo_0.0.1_* > subject.checksums.txt
|
||||||
|
|
||||||
|
- uses: actions/attest@v2
|
||||||
|
with:
|
||||||
|
subject-checksums: subject.checksums.txt
|
||||||
|
predicate-type: 'https://example.com/predicate/v1'
|
||||||
|
predicate: '{}'
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- markdownlint-disable MD038 -->
|
||||||
|
|
||||||
|
The file referenced by the `subject-checksums` input must conform to the same
|
||||||
|
format used by the shasum tools. Each subject should be listed on a separate
|
||||||
|
line including the hex-encoded digest (either SHA256 or SHA512), a space, a
|
||||||
|
single character flag indicating either binary (`*`) or text (` `) input mode,
|
||||||
|
and the filename.
|
||||||
|
|
||||||
|
<!-- markdownlint-enable MD038 -->
|
||||||
|
|
||||||
|
```text
|
||||||
|
b569bf992b287f55d78bf8ee476497e9b7e9d2bf1c338860bfb905016218c740 foo_0.0.1_darwin_amd64
|
||||||
|
a54fc515e616cac7fcf11a49d5c5ec9ec315948a5935c1e11dd610b834b14dde foo_0.0.1_darwin_arm64
|
||||||
|
```
|
||||||
|
|
||||||
### Container Image
|
### Container Image
|
||||||
|
|
||||||
When working with container images you can invoke the action with the
|
When working with container images you can invoke the action with the
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ describe('index', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
getBooleanInputMock.mockImplementation(() => false)
|
getBooleanInputMock.mockImplementation(() => false)
|
||||||
})
|
})
|
||||||
it('calls run when imported', async () => {
|
it('calls run when imported', () => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||||
require('../src/index')
|
require('../src/index')
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ const defaultInputs: main.RunInputs = {
|
|||||||
subjectName: '',
|
subjectName: '',
|
||||||
subjectDigest: '',
|
subjectDigest: '',
|
||||||
subjectPath: '',
|
subjectPath: '',
|
||||||
|
subjectChecksums: '',
|
||||||
pushToRegistry: false,
|
pushToRegistry: false,
|
||||||
showSummary: true,
|
showSummary: true,
|
||||||
githubToken: '',
|
githubToken: '',
|
||||||
@@ -138,7 +139,9 @@ describe('action', () => {
|
|||||||
|
|
||||||
expect(runMock).toHaveReturned()
|
expect(runMock).toHaveReturned()
|
||||||
expect(setFailedMock).toHaveBeenCalledWith(
|
expect(setFailedMock).toHaveBeenCalledWith(
|
||||||
new Error('One of subject-path or subject-digest must be provided')
|
new Error(
|
||||||
|
'One of subject-path, subject-digest, or subject-checksums must be provided'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ describe('subjectFromInputs', () => {
|
|||||||
const blankInputs: SubjectInputs = {
|
const blankInputs: SubjectInputs = {
|
||||||
subjectPath: '',
|
subjectPath: '',
|
||||||
subjectName: '',
|
subjectName: '',
|
||||||
subjectDigest: ''
|
subjectDigest: '',
|
||||||
|
subjectChecksums: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('when no inputs are provided', () => {
|
describe('when no inputs are provided', () => {
|
||||||
it('throws an error', async () => {
|
it('throws an error', async () => {
|
||||||
await expect(subjectFromInputs(blankInputs)).rejects.toThrow(
|
await expect(subjectFromInputs(blankInputs)).rejects.toThrow(
|
||||||
/one of subject-path or subject-digest must be provided/i
|
/one of subject-path, subject-digest, or subject-checksums must be provided/i
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -28,11 +29,42 @@ describe('subjectFromInputs', () => {
|
|||||||
const inputs: SubjectInputs = {
|
const inputs: SubjectInputs = {
|
||||||
subjectName: 'foo',
|
subjectName: 'foo',
|
||||||
subjectPath: 'path/to/subject',
|
subjectPath: 'path/to/subject',
|
||||||
subjectDigest: 'digest'
|
subjectDigest: 'digest',
|
||||||
|
subjectChecksums: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||||
/only one of subject-path or subject-digest may be provided/i
|
/only one of subject-path, subject-digest, or subject-checksums may be provided/i
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when both subject path and subject checksums are provided', () => {
|
||||||
|
it('throws an error', async () => {
|
||||||
|
const inputs: SubjectInputs = {
|
||||||
|
subjectName: '',
|
||||||
|
subjectPath: 'path/to/subject',
|
||||||
|
subjectDigest: '',
|
||||||
|
subjectChecksums: 'path/to/checksums'
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||||
|
/only one of subject-path, subject-digest, or subject-checksums may be provided/i
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when both subject digest and subject checksums are provided', () => {
|
||||||
|
it('throws an error', async () => {
|
||||||
|
const inputs: SubjectInputs = {
|
||||||
|
subjectName: 'foo',
|
||||||
|
subjectPath: '',
|
||||||
|
subjectDigest: 'digest',
|
||||||
|
subjectChecksums: 'path/to/checksums'
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||||
|
/only one of subject-path, subject-digest, or subject-checksums may be provided/i
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -232,7 +264,6 @@ describe('subjectFromInputs', () => {
|
|||||||
expect(subjects).toBeDefined()
|
expect(subjects).toBeDefined()
|
||||||
expect(subjects).toHaveLength(3)
|
expect(subjects).toHaveLength(3)
|
||||||
|
|
||||||
/* eslint-disable-next-line github/array-foreach */
|
|
||||||
subjects.forEach((subject, i) => {
|
subjects.forEach((subject, i) => {
|
||||||
expect(subject.name).toEqual(`${filename}-${i}`)
|
expect(subject.name).toEqual(`${filename}-${i}`)
|
||||||
expect(subject.digest).toEqual({ sha256: expectedDigest })
|
expect(subject.digest).toEqual({ sha256: expectedDigest })
|
||||||
@@ -388,6 +419,118 @@ describe('subjectFromInputs', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('when specifying a subject checksums file', () => {
|
||||||
|
const checksums = `
|
||||||
|
187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d demo_0.0.1_linux_amd64
|
||||||
|
badline
|
||||||
|
5d8b4751ef31f9440d843fcfa4e53ca2e25b1cb1f13fd355fdc7c24b41fe645293291ea9297ba3989078abb77ebbaac66be073618a9e4974dbd0361881d4c718 demo_0.0.1_darwin_arm64`
|
||||||
|
|
||||||
|
let dir = ''
|
||||||
|
const filename = 'checksums'
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
// Set-up temp directory
|
||||||
|
const tmpDir = await fs.realpath(os.tmpdir())
|
||||||
|
dir = await fs.mkdtemp(tmpDir + path.sep)
|
||||||
|
|
||||||
|
// Write file to temp directory
|
||||||
|
await fs.writeFile(path.join(dir, filename), checksums)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
// Clean-up temp directory
|
||||||
|
await fs.rm(dir, { recursive: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when the specified path is NOT a file', () => {
|
||||||
|
it('throws an error', async () => {
|
||||||
|
const inputs: SubjectInputs = {
|
||||||
|
...blankInputs,
|
||||||
|
subjectChecksums: dir
|
||||||
|
}
|
||||||
|
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||||
|
/subject checksums file not found/i
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when the specific path is a file', () => {
|
||||||
|
it('returns the multiple subjects', async () => {
|
||||||
|
const inputs: SubjectInputs = {
|
||||||
|
...blankInputs,
|
||||||
|
subjectChecksums: path.join(dir, filename)
|
||||||
|
}
|
||||||
|
const subjects = await subjectFromInputs(inputs)
|
||||||
|
|
||||||
|
expect(subjects).toBeDefined()
|
||||||
|
expect(subjects).toHaveLength(2)
|
||||||
|
|
||||||
|
expect(subjects).toContainEqual({
|
||||||
|
name: 'demo_0.0.1_linux_amd64',
|
||||||
|
digest: {
|
||||||
|
sha256:
|
||||||
|
'187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when specifying a subject checksums string', () => {
|
||||||
|
const checksums = `
|
||||||
|
f861e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e demo_0.0.1_linux_386
|
||||||
|
187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d demo_0.0.1_linux_amd64
|
||||||
|
9ecbf449e286a8a8748c161c52aa28b6b2fc64ab86f94161c5d1b3abc18156c5 demo_0.0.1_linux_arm64`
|
||||||
|
|
||||||
|
it('returns the multiple subjects', async () => {
|
||||||
|
const inputs: SubjectInputs = {
|
||||||
|
...blankInputs,
|
||||||
|
subjectChecksums: checksums
|
||||||
|
}
|
||||||
|
const subjects = await subjectFromInputs(inputs)
|
||||||
|
|
||||||
|
expect(subjects).toBeDefined()
|
||||||
|
expect(subjects).toHaveLength(3)
|
||||||
|
|
||||||
|
expect(subjects).toContainEqual({
|
||||||
|
name: 'demo_0.0.1_linux_386',
|
||||||
|
digest: {
|
||||||
|
sha256:
|
||||||
|
'f861e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when specifying a subject checksums string with an unrecognized digest', () => {
|
||||||
|
const checksums = `f861e demo_0.0.1_linux_386`
|
||||||
|
|
||||||
|
it('throws an error', async () => {
|
||||||
|
const inputs: SubjectInputs = {
|
||||||
|
...blankInputs,
|
||||||
|
subjectChecksums: checksums
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect(subjectFromInputs(inputs)).rejects.toThrow(
|
||||||
|
/unknown digest algorithm/i
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when specifying a subject checksums string with an invalid digest', () => {
|
||||||
|
const checksums =
|
||||||
|
'!!!!e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e demo_0.0.1_linux_386'
|
||||||
|
|
||||||
|
it('throws an error', async () => {
|
||||||
|
const inputs: SubjectInputs = {
|
||||||
|
...blankInputs,
|
||||||
|
subjectChecksums: checksums
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect(subjectFromInputs(inputs)).rejects.toThrow(/invalid digest/i)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('subjectDigest', () => {
|
describe('subjectDigest', () => {
|
||||||
|
|||||||
18
action.yml
18
action.yml
@@ -9,20 +9,26 @@ inputs:
|
|||||||
subject-path:
|
subject-path:
|
||||||
description: >
|
description: >
|
||||||
Path to the artifact serving as the subject of the attestation. Must
|
Path to the artifact serving as the subject of the attestation. Must
|
||||||
specify exactly one of "subject-path" or "subject-digest". May contain a
|
specify exactly one of "subject-path", "subject-digest", or
|
||||||
glob pattern or list of paths (total subject count cannot exceed 1024).
|
"subject-checksums". May contain a glob pattern or list of paths (total
|
||||||
|
subject count cannot exceed 1024).
|
||||||
required: false
|
required: false
|
||||||
subject-digest:
|
subject-digest:
|
||||||
description: >
|
description: >
|
||||||
Digest of the subject for the attestation. Must be in the form
|
Digest of the subject for the attestation. Must be in the form
|
||||||
"algorithm:hex_digest" (e.g. "sha256:abc123..."). Must specify exactly one
|
"algorithm:hex_digest" (e.g. "sha256:abc123..."). Must specify exactly one
|
||||||
of "subject-path" or "subject-digest".
|
of "subject-path", "subject-digest", or "subject-checksums".
|
||||||
required: false
|
required: false
|
||||||
subject-name:
|
subject-name:
|
||||||
description: >
|
description: >
|
||||||
Subject name as it should appear in the attestation. Required unless
|
Subject name as it should appear in the attestation. Required when
|
||||||
"subject-path" is specified, in which case it will be inferred from the
|
identifying the subject with the "subject-digest" input.
|
||||||
path.
|
required: false
|
||||||
|
subject-checksums:
|
||||||
|
description: >
|
||||||
|
Path to checksums file containing digest and name of subjects for
|
||||||
|
attestation. Must specify exactly one of "subject-path", "subject-digest",
|
||||||
|
or "subject-checksums".
|
||||||
required: false
|
required: false
|
||||||
predicate-type:
|
predicate-type:
|
||||||
description: >
|
description: >
|
||||||
|
|||||||
234
dist/index.js
generated
vendored
234
dist/index.js
generated
vendored
@@ -28485,7 +28485,7 @@ Object.defineProperty(exports, "cryptoRuntime", ({ enumerable: true, get: functi
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.compactDecrypt = void 0;
|
exports.compactDecrypt = compactDecrypt;
|
||||||
const decrypt_js_1 = __nccwpck_require__(59344);
|
const decrypt_js_1 = __nccwpck_require__(59344);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
||||||
@@ -28513,7 +28513,6 @@ async function compactDecrypt(jwe, key, options) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.compactDecrypt = compactDecrypt;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -28563,7 +28562,7 @@ exports.CompactEncrypt = CompactEncrypt;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.flattenedDecrypt = void 0;
|
exports.flattenedDecrypt = flattenedDecrypt;
|
||||||
const base64url_js_1 = __nccwpck_require__(12635);
|
const base64url_js_1 = __nccwpck_require__(12635);
|
||||||
const decrypt_js_1 = __nccwpck_require__(52806);
|
const decrypt_js_1 = __nccwpck_require__(52806);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
@@ -28725,7 +28724,6 @@ async function flattenedDecrypt(jwe, key, options) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.flattenedDecrypt = flattenedDecrypt;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -28909,7 +28907,7 @@ exports.FlattenedEncrypt = FlattenedEncrypt;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.generalDecrypt = void 0;
|
exports.generalDecrypt = generalDecrypt;
|
||||||
const decrypt_js_1 = __nccwpck_require__(59344);
|
const decrypt_js_1 = __nccwpck_require__(59344);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const is_object_js_1 = __nccwpck_require__(92242);
|
const is_object_js_1 = __nccwpck_require__(92242);
|
||||||
@@ -28941,7 +28939,6 @@ async function generalDecrypt(jwe, key, options) {
|
|||||||
}
|
}
|
||||||
throw new errors_js_1.JWEDecryptionFailed();
|
throw new errors_js_1.JWEDecryptionFailed();
|
||||||
}
|
}
|
||||||
exports.generalDecrypt = generalDecrypt;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -29146,7 +29143,7 @@ exports.GeneralEncrypt = GeneralEncrypt;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.EmbeddedJWK = void 0;
|
exports.EmbeddedJWK = EmbeddedJWK;
|
||||||
const import_js_1 = __nccwpck_require__(45647);
|
const import_js_1 = __nccwpck_require__(45647);
|
||||||
const is_object_js_1 = __nccwpck_require__(92242);
|
const is_object_js_1 = __nccwpck_require__(92242);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
@@ -29164,7 +29161,6 @@ async function EmbeddedJWK(protectedHeader, token) {
|
|||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
exports.EmbeddedJWK = EmbeddedJWK;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -29175,7 +29171,8 @@ exports.EmbeddedJWK = EmbeddedJWK;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.calculateJwkThumbprintUri = exports.calculateJwkThumbprint = void 0;
|
exports.calculateJwkThumbprint = calculateJwkThumbprint;
|
||||||
|
exports.calculateJwkThumbprintUri = calculateJwkThumbprintUri;
|
||||||
const digest_js_1 = __nccwpck_require__(12931);
|
const digest_js_1 = __nccwpck_require__(12931);
|
||||||
const base64url_js_1 = __nccwpck_require__(12635);
|
const base64url_js_1 = __nccwpck_require__(12635);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
@@ -29224,13 +29221,11 @@ async function calculateJwkThumbprint(jwk, digestAlgorithm) {
|
|||||||
const data = buffer_utils_js_1.encoder.encode(JSON.stringify(components));
|
const data = buffer_utils_js_1.encoder.encode(JSON.stringify(components));
|
||||||
return (0, base64url_js_1.encode)(await (0, digest_js_1.default)(digestAlgorithm, data));
|
return (0, base64url_js_1.encode)(await (0, digest_js_1.default)(digestAlgorithm, data));
|
||||||
}
|
}
|
||||||
exports.calculateJwkThumbprint = calculateJwkThumbprint;
|
|
||||||
async function calculateJwkThumbprintUri(jwk, digestAlgorithm) {
|
async function calculateJwkThumbprintUri(jwk, digestAlgorithm) {
|
||||||
digestAlgorithm ??= 'sha256';
|
digestAlgorithm ??= 'sha256';
|
||||||
const thumbprint = await calculateJwkThumbprint(jwk, digestAlgorithm);
|
const thumbprint = await calculateJwkThumbprint(jwk, digestAlgorithm);
|
||||||
return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;
|
return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;
|
||||||
}
|
}
|
||||||
exports.calculateJwkThumbprintUri = calculateJwkThumbprintUri;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -29241,7 +29236,7 @@ exports.calculateJwkThumbprintUri = calculateJwkThumbprintUri;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.createLocalJWKSet = void 0;
|
exports.createLocalJWKSet = createLocalJWKSet;
|
||||||
const import_js_1 = __nccwpck_require__(45647);
|
const import_js_1 = __nccwpck_require__(45647);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const is_object_js_1 = __nccwpck_require__(92242);
|
const is_object_js_1 = __nccwpck_require__(92242);
|
||||||
@@ -29364,7 +29359,6 @@ function createLocalJWKSet(jwks) {
|
|||||||
});
|
});
|
||||||
return localJWKSet;
|
return localJWKSet;
|
||||||
}
|
}
|
||||||
exports.createLocalJWKSet = createLocalJWKSet;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -29375,7 +29369,8 @@ exports.createLocalJWKSet = createLocalJWKSet;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.experimental_jwksCache = exports.createRemoteJWKSet = exports.jwksCache = void 0;
|
exports.experimental_jwksCache = exports.jwksCache = void 0;
|
||||||
|
exports.createRemoteJWKSet = createRemoteJWKSet;
|
||||||
const fetch_jwks_js_1 = __nccwpck_require__(20311);
|
const fetch_jwks_js_1 = __nccwpck_require__(20311);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const local_js_1 = __nccwpck_require__(25275);
|
const local_js_1 = __nccwpck_require__(25275);
|
||||||
@@ -29388,7 +29383,7 @@ function isCloudflareWorkers() {
|
|||||||
let USER_AGENT;
|
let USER_AGENT;
|
||||||
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
if (typeof navigator === 'undefined' || !navigator.userAgent?.startsWith?.('Mozilla/5.0 ')) {
|
||||||
const NAME = 'jose';
|
const NAME = 'jose';
|
||||||
const VERSION = 'v5.9.4';
|
const VERSION = 'v5.9.6';
|
||||||
USER_AGENT = `${NAME}/${VERSION}`;
|
USER_AGENT = `${NAME}/${VERSION}`;
|
||||||
}
|
}
|
||||||
exports.jwksCache = Symbol();
|
exports.jwksCache = Symbol();
|
||||||
@@ -29523,7 +29518,6 @@ function createRemoteJWKSet(url, options) {
|
|||||||
});
|
});
|
||||||
return remoteJWKSet;
|
return remoteJWKSet;
|
||||||
}
|
}
|
||||||
exports.createRemoteJWKSet = createRemoteJWKSet;
|
|
||||||
exports.experimental_jwksCache = exports.jwksCache;
|
exports.experimental_jwksCache = exports.jwksCache;
|
||||||
|
|
||||||
|
|
||||||
@@ -29565,7 +29559,7 @@ exports.CompactSign = CompactSign;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.compactVerify = void 0;
|
exports.compactVerify = compactVerify;
|
||||||
const verify_js_1 = __nccwpck_require__(56358);
|
const verify_js_1 = __nccwpck_require__(56358);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
||||||
@@ -29587,7 +29581,6 @@ async function compactVerify(jws, key, options) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.compactVerify = compactVerify;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -29694,7 +29687,7 @@ exports.FlattenedSign = FlattenedSign;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.flattenedVerify = void 0;
|
exports.flattenedVerify = flattenedVerify;
|
||||||
const base64url_js_1 = __nccwpck_require__(12635);
|
const base64url_js_1 = __nccwpck_require__(12635);
|
||||||
const verify_js_1 = __nccwpck_require__(11242);
|
const verify_js_1 = __nccwpck_require__(11242);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
@@ -29817,7 +29810,6 @@ async function flattenedVerify(jws, key, options) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.flattenedVerify = flattenedVerify;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -29913,7 +29905,7 @@ exports.GeneralSign = GeneralSign;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.generalVerify = void 0;
|
exports.generalVerify = generalVerify;
|
||||||
const verify_js_1 = __nccwpck_require__(56358);
|
const verify_js_1 = __nccwpck_require__(56358);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const is_object_js_1 = __nccwpck_require__(92242);
|
const is_object_js_1 = __nccwpck_require__(92242);
|
||||||
@@ -29938,7 +29930,6 @@ async function generalVerify(jws, key, options) {
|
|||||||
}
|
}
|
||||||
throw new errors_js_1.JWSSignatureVerificationFailed();
|
throw new errors_js_1.JWSSignatureVerificationFailed();
|
||||||
}
|
}
|
||||||
exports.generalVerify = generalVerify;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -29949,7 +29940,7 @@ exports.generalVerify = generalVerify;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.jwtDecrypt = void 0;
|
exports.jwtDecrypt = jwtDecrypt;
|
||||||
const decrypt_js_1 = __nccwpck_require__(14298);
|
const decrypt_js_1 = __nccwpck_require__(14298);
|
||||||
const jwt_claims_set_js_1 = __nccwpck_require__(13354);
|
const jwt_claims_set_js_1 = __nccwpck_require__(13354);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
@@ -29973,7 +29964,6 @@ async function jwtDecrypt(jwt, key, options) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.jwtDecrypt = jwtDecrypt;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30236,7 +30226,7 @@ exports.UnsecuredJWT = UnsecuredJWT;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.jwtVerify = void 0;
|
exports.jwtVerify = jwtVerify;
|
||||||
const verify_js_1 = __nccwpck_require__(94212);
|
const verify_js_1 = __nccwpck_require__(94212);
|
||||||
const jwt_claims_set_js_1 = __nccwpck_require__(13354);
|
const jwt_claims_set_js_1 = __nccwpck_require__(13354);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
@@ -30252,7 +30242,6 @@ async function jwtVerify(jwt, key, options) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.jwtVerify = jwtVerify;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30263,22 +30252,21 @@ exports.jwtVerify = jwtVerify;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.exportJWK = exports.exportPKCS8 = exports.exportSPKI = void 0;
|
exports.exportSPKI = exportSPKI;
|
||||||
|
exports.exportPKCS8 = exportPKCS8;
|
||||||
|
exports.exportJWK = exportJWK;
|
||||||
const asn1_js_1 = __nccwpck_require__(12774);
|
const asn1_js_1 = __nccwpck_require__(12774);
|
||||||
const asn1_js_2 = __nccwpck_require__(12774);
|
const asn1_js_2 = __nccwpck_require__(12774);
|
||||||
const key_to_jwk_js_1 = __nccwpck_require__(9041);
|
const key_to_jwk_js_1 = __nccwpck_require__(9041);
|
||||||
async function exportSPKI(key) {
|
async function exportSPKI(key) {
|
||||||
return (0, asn1_js_1.toSPKI)(key);
|
return (0, asn1_js_1.toSPKI)(key);
|
||||||
}
|
}
|
||||||
exports.exportSPKI = exportSPKI;
|
|
||||||
async function exportPKCS8(key) {
|
async function exportPKCS8(key) {
|
||||||
return (0, asn1_js_2.toPKCS8)(key);
|
return (0, asn1_js_2.toPKCS8)(key);
|
||||||
}
|
}
|
||||||
exports.exportPKCS8 = exportPKCS8;
|
|
||||||
async function exportJWK(key) {
|
async function exportJWK(key) {
|
||||||
return (0, key_to_jwk_js_1.default)(key);
|
return (0, key_to_jwk_js_1.default)(key);
|
||||||
}
|
}
|
||||||
exports.exportJWK = exportJWK;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30289,12 +30277,11 @@ exports.exportJWK = exportJWK;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.generateKeyPair = void 0;
|
exports.generateKeyPair = generateKeyPair;
|
||||||
const generate_js_1 = __nccwpck_require__(10088);
|
const generate_js_1 = __nccwpck_require__(10088);
|
||||||
async function generateKeyPair(alg, options) {
|
async function generateKeyPair(alg, options) {
|
||||||
return (0, generate_js_1.generateKeyPair)(alg, options);
|
return (0, generate_js_1.generateKeyPair)(alg, options);
|
||||||
}
|
}
|
||||||
exports.generateKeyPair = generateKeyPair;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30305,12 +30292,11 @@ exports.generateKeyPair = generateKeyPair;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.generateSecret = void 0;
|
exports.generateSecret = generateSecret;
|
||||||
const generate_js_1 = __nccwpck_require__(10088);
|
const generate_js_1 = __nccwpck_require__(10088);
|
||||||
async function generateSecret(alg, options) {
|
async function generateSecret(alg, options) {
|
||||||
return (0, generate_js_1.generateSecret)(alg, options);
|
return (0, generate_js_1.generateSecret)(alg, options);
|
||||||
}
|
}
|
||||||
exports.generateSecret = generateSecret;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30321,7 +30307,10 @@ exports.generateSecret = generateSecret;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.importJWK = exports.importPKCS8 = exports.importX509 = exports.importSPKI = void 0;
|
exports.importSPKI = importSPKI;
|
||||||
|
exports.importX509 = importX509;
|
||||||
|
exports.importPKCS8 = importPKCS8;
|
||||||
|
exports.importJWK = importJWK;
|
||||||
const base64url_js_1 = __nccwpck_require__(12635);
|
const base64url_js_1 = __nccwpck_require__(12635);
|
||||||
const asn1_js_1 = __nccwpck_require__(12774);
|
const asn1_js_1 = __nccwpck_require__(12774);
|
||||||
const jwk_to_key_js_1 = __nccwpck_require__(80939);
|
const jwk_to_key_js_1 = __nccwpck_require__(80939);
|
||||||
@@ -30333,21 +30322,18 @@ async function importSPKI(spki, alg, options) {
|
|||||||
}
|
}
|
||||||
return (0, asn1_js_1.fromSPKI)(spki, alg, options);
|
return (0, asn1_js_1.fromSPKI)(spki, alg, options);
|
||||||
}
|
}
|
||||||
exports.importSPKI = importSPKI;
|
|
||||||
async function importX509(x509, alg, options) {
|
async function importX509(x509, alg, options) {
|
||||||
if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) {
|
if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) {
|
||||||
throw new TypeError('"x509" must be X.509 formatted string');
|
throw new TypeError('"x509" must be X.509 formatted string');
|
||||||
}
|
}
|
||||||
return (0, asn1_js_1.fromX509)(x509, alg, options);
|
return (0, asn1_js_1.fromX509)(x509, alg, options);
|
||||||
}
|
}
|
||||||
exports.importX509 = importX509;
|
|
||||||
async function importPKCS8(pkcs8, alg, options) {
|
async function importPKCS8(pkcs8, alg, options) {
|
||||||
if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) {
|
if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) {
|
||||||
throw new TypeError('"pkcs8" must be PKCS#8 formatted string');
|
throw new TypeError('"pkcs8" must be PKCS#8 formatted string');
|
||||||
}
|
}
|
||||||
return (0, asn1_js_1.fromPKCS8)(pkcs8, alg, options);
|
return (0, asn1_js_1.fromPKCS8)(pkcs8, alg, options);
|
||||||
}
|
}
|
||||||
exports.importPKCS8 = importPKCS8;
|
|
||||||
async function importJWK(jwk, alg) {
|
async function importJWK(jwk, alg) {
|
||||||
if (!(0, is_object_js_1.default)(jwk)) {
|
if (!(0, is_object_js_1.default)(jwk)) {
|
||||||
throw new TypeError('JWK must be an object');
|
throw new TypeError('JWK must be an object');
|
||||||
@@ -30370,7 +30356,6 @@ async function importJWK(jwk, alg) {
|
|||||||
throw new errors_js_1.JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
|
throw new errors_js_1.JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.importJWK = importJWK;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30381,7 +30366,8 @@ exports.importJWK = importJWK;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.unwrap = exports.wrap = void 0;
|
exports.wrap = wrap;
|
||||||
|
exports.unwrap = unwrap;
|
||||||
const encrypt_js_1 = __nccwpck_require__(36286);
|
const encrypt_js_1 = __nccwpck_require__(36286);
|
||||||
const decrypt_js_1 = __nccwpck_require__(52806);
|
const decrypt_js_1 = __nccwpck_require__(52806);
|
||||||
const base64url_js_1 = __nccwpck_require__(12635);
|
const base64url_js_1 = __nccwpck_require__(12635);
|
||||||
@@ -30394,12 +30380,10 @@ async function wrap(alg, key, cek, iv) {
|
|||||||
tag: (0, base64url_js_1.encode)(wrapped.tag),
|
tag: (0, base64url_js_1.encode)(wrapped.tag),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.wrap = wrap;
|
|
||||||
async function unwrap(alg, key, encryptedKey, iv, tag) {
|
async function unwrap(alg, key, encryptedKey, iv, tag) {
|
||||||
const jweAlgorithm = alg.slice(0, 7);
|
const jweAlgorithm = alg.slice(0, 7);
|
||||||
return (0, decrypt_js_1.default)(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0));
|
return (0, decrypt_js_1.default)(jweAlgorithm, key, encryptedKey, iv, tag, new Uint8Array(0));
|
||||||
}
|
}
|
||||||
exports.unwrap = unwrap;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30410,7 +30394,13 @@ exports.unwrap = unwrap;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.concatKdf = exports.lengthAndInput = exports.uint32be = exports.uint64be = exports.p2s = exports.concat = exports.decoder = exports.encoder = void 0;
|
exports.decoder = exports.encoder = void 0;
|
||||||
|
exports.concat = concat;
|
||||||
|
exports.p2s = p2s;
|
||||||
|
exports.uint64be = uint64be;
|
||||||
|
exports.uint32be = uint32be;
|
||||||
|
exports.lengthAndInput = lengthAndInput;
|
||||||
|
exports.concatKdf = concatKdf;
|
||||||
const digest_js_1 = __nccwpck_require__(12931);
|
const digest_js_1 = __nccwpck_require__(12931);
|
||||||
exports.encoder = new TextEncoder();
|
exports.encoder = new TextEncoder();
|
||||||
exports.decoder = new TextDecoder();
|
exports.decoder = new TextDecoder();
|
||||||
@@ -30425,11 +30415,9 @@ function concat(...buffers) {
|
|||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
exports.concat = concat;
|
|
||||||
function p2s(alg, p2sInput) {
|
function p2s(alg, p2sInput) {
|
||||||
return concat(exports.encoder.encode(alg), new Uint8Array([0]), p2sInput);
|
return concat(exports.encoder.encode(alg), new Uint8Array([0]), p2sInput);
|
||||||
}
|
}
|
||||||
exports.p2s = p2s;
|
|
||||||
function writeUInt32BE(buf, value, offset) {
|
function writeUInt32BE(buf, value, offset) {
|
||||||
if (value < 0 || value >= MAX_INT32) {
|
if (value < 0 || value >= MAX_INT32) {
|
||||||
throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`);
|
throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`);
|
||||||
@@ -30444,17 +30432,14 @@ function uint64be(value) {
|
|||||||
writeUInt32BE(buf, low, 4);
|
writeUInt32BE(buf, low, 4);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
exports.uint64be = uint64be;
|
|
||||||
function uint32be(value) {
|
function uint32be(value) {
|
||||||
const buf = new Uint8Array(4);
|
const buf = new Uint8Array(4);
|
||||||
writeUInt32BE(buf, value);
|
writeUInt32BE(buf, value);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
exports.uint32be = uint32be;
|
|
||||||
function lengthAndInput(input) {
|
function lengthAndInput(input) {
|
||||||
return concat(uint32be(input.length), input);
|
return concat(uint32be(input.length), input);
|
||||||
}
|
}
|
||||||
exports.lengthAndInput = lengthAndInput;
|
|
||||||
async function concatKdf(secret, bits, value) {
|
async function concatKdf(secret, bits, value) {
|
||||||
const iterations = Math.ceil((bits >> 3) / 32);
|
const iterations = Math.ceil((bits >> 3) / 32);
|
||||||
const res = new Uint8Array(iterations * 32);
|
const res = new Uint8Array(iterations * 32);
|
||||||
@@ -30467,7 +30452,6 @@ async function concatKdf(secret, bits, value) {
|
|||||||
}
|
}
|
||||||
return res.slice(0, bits >> 3);
|
return res.slice(0, bits >> 3);
|
||||||
}
|
}
|
||||||
exports.concatKdf = concatKdf;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30478,7 +30462,7 @@ exports.concatKdf = concatKdf;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.bitLength = void 0;
|
exports.bitLength = bitLength;
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const random_js_1 = __nccwpck_require__(23376);
|
const random_js_1 = __nccwpck_require__(23376);
|
||||||
function bitLength(alg) {
|
function bitLength(alg) {
|
||||||
@@ -30498,7 +30482,6 @@ function bitLength(alg) {
|
|||||||
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.bitLength = bitLength;
|
|
||||||
exports["default"] = (alg) => (0, random_js_1.default)(new Uint8Array(bitLength(alg) >> 3));
|
exports["default"] = (alg) => (0, random_js_1.default)(new Uint8Array(bitLength(alg) >> 3));
|
||||||
|
|
||||||
|
|
||||||
@@ -30616,13 +30599,13 @@ exports.checkKeyTypeWithJwk = checkKeyType.bind(undefined, true);
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports["default"] = checkP2s;
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
function checkP2s(p2s) {
|
function checkP2s(p2s) {
|
||||||
if (!(p2s instanceof Uint8Array) || p2s.length < 8) {
|
if (!(p2s instanceof Uint8Array) || p2s.length < 8) {
|
||||||
throw new errors_js_1.JWEInvalid('PBES2 Salt Input must be 8 or more octets');
|
throw new errors_js_1.JWEInvalid('PBES2 Salt Input must be 8 or more octets');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports["default"] = checkP2s;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -30633,7 +30616,8 @@ exports["default"] = checkP2s;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.checkEncCryptoKey = exports.checkSigCryptoKey = void 0;
|
exports.checkSigCryptoKey = checkSigCryptoKey;
|
||||||
|
exports.checkEncCryptoKey = checkEncCryptoKey;
|
||||||
function unusable(name, prop = 'algorithm.name') {
|
function unusable(name, prop = 'algorithm.name') {
|
||||||
return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
return new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
|
||||||
}
|
}
|
||||||
@@ -30728,7 +30712,6 @@ function checkSigCryptoKey(key, alg, ...usages) {
|
|||||||
}
|
}
|
||||||
checkUsage(key, usages);
|
checkUsage(key, usages);
|
||||||
}
|
}
|
||||||
exports.checkSigCryptoKey = checkSigCryptoKey;
|
|
||||||
function checkEncCryptoKey(key, alg, ...usages) {
|
function checkEncCryptoKey(key, alg, ...usages) {
|
||||||
switch (alg) {
|
switch (alg) {
|
||||||
case 'A128GCM':
|
case 'A128GCM':
|
||||||
@@ -30787,7 +30770,6 @@ function checkEncCryptoKey(key, alg, ...usages) {
|
|||||||
}
|
}
|
||||||
checkUsage(key, usages);
|
checkUsage(key, usages);
|
||||||
}
|
}
|
||||||
exports.checkEncCryptoKey = checkEncCryptoKey;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -31047,7 +31029,7 @@ exports["default"] = (date) => Math.floor(date.getTime() / 1000);
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.withAlg = void 0;
|
exports.withAlg = withAlg;
|
||||||
function message(msg, actual, ...types) {
|
function message(msg, actual, ...types) {
|
||||||
types = types.filter(Boolean);
|
types = types.filter(Boolean);
|
||||||
if (types.length > 2) {
|
if (types.length > 2) {
|
||||||
@@ -31079,7 +31061,6 @@ exports["default"] = (actual, ...types) => {
|
|||||||
function withAlg(alg, actual, ...types) {
|
function withAlg(alg, actual, ...types) {
|
||||||
return message(`Key for the ${alg} algorithm must be `, actual, ...types);
|
return message(`Key for the ${alg} algorithm must be `, actual, ...types);
|
||||||
}
|
}
|
||||||
exports.withAlg = withAlg;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -31122,24 +31103,23 @@ exports["default"] = isDisjoint;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.isSecretJWK = exports.isPublicJWK = exports.isPrivateJWK = exports.isJWK = void 0;
|
exports.isJWK = isJWK;
|
||||||
|
exports.isPrivateJWK = isPrivateJWK;
|
||||||
|
exports.isPublicJWK = isPublicJWK;
|
||||||
|
exports.isSecretJWK = isSecretJWK;
|
||||||
const is_object_js_1 = __nccwpck_require__(92242);
|
const is_object_js_1 = __nccwpck_require__(92242);
|
||||||
function isJWK(key) {
|
function isJWK(key) {
|
||||||
return (0, is_object_js_1.default)(key) && typeof key.kty === 'string';
|
return (0, is_object_js_1.default)(key) && typeof key.kty === 'string';
|
||||||
}
|
}
|
||||||
exports.isJWK = isJWK;
|
|
||||||
function isPrivateJWK(key) {
|
function isPrivateJWK(key) {
|
||||||
return key.kty !== 'oct' && typeof key.d === 'string';
|
return key.kty !== 'oct' && typeof key.d === 'string';
|
||||||
}
|
}
|
||||||
exports.isPrivateJWK = isPrivateJWK;
|
|
||||||
function isPublicJWK(key) {
|
function isPublicJWK(key) {
|
||||||
return key.kty !== 'oct' && typeof key.d === 'undefined';
|
return key.kty !== 'oct' && typeof key.d === 'undefined';
|
||||||
}
|
}
|
||||||
exports.isPublicJWK = isPublicJWK;
|
|
||||||
function isSecretJWK(key) {
|
function isSecretJWK(key) {
|
||||||
return isJWK(key) && key.kty === 'oct' && typeof key.k === 'string';
|
return isJWK(key) && key.kty === 'oct' && typeof key.k === 'string';
|
||||||
}
|
}
|
||||||
exports.isSecretJWK = isSecretJWK;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -31150,6 +31130,7 @@ exports.isSecretJWK = isSecretJWK;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports["default"] = isObject;
|
||||||
function isObjectLike(value) {
|
function isObjectLike(value) {
|
||||||
return typeof value === 'object' && value !== null;
|
return typeof value === 'object' && value !== null;
|
||||||
}
|
}
|
||||||
@@ -31166,7 +31147,6 @@ function isObject(input) {
|
|||||||
}
|
}
|
||||||
return Object.getPrototypeOf(input) === proto;
|
return Object.getPrototypeOf(input) === proto;
|
||||||
}
|
}
|
||||||
exports["default"] = isObject;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -31177,7 +31157,7 @@ exports["default"] = isObject;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.bitLength = void 0;
|
exports.bitLength = bitLength;
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
const random_js_1 = __nccwpck_require__(23376);
|
const random_js_1 = __nccwpck_require__(23376);
|
||||||
function bitLength(alg) {
|
function bitLength(alg) {
|
||||||
@@ -31197,7 +31177,6 @@ function bitLength(alg) {
|
|||||||
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
throw new errors_js_1.JOSENotSupported(`Unsupported JWE Algorithm: ${alg}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.bitLength = bitLength;
|
|
||||||
exports["default"] = (alg) => (0, random_js_1.default)(new Uint8Array(bitLength(alg) >> 3));
|
exports["default"] = (alg) => (0, random_js_1.default)(new Uint8Array(bitLength(alg) >> 3));
|
||||||
|
|
||||||
|
|
||||||
@@ -31618,6 +31597,7 @@ exports.decode = decode;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports["default"] = cbcTag;
|
||||||
const node_crypto_1 = __nccwpck_require__(77598);
|
const node_crypto_1 = __nccwpck_require__(77598);
|
||||||
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
||||||
function cbcTag(aad, iv, ciphertext, macSize, macKey, keySize) {
|
function cbcTag(aad, iv, ciphertext, macSize, macKey, keySize) {
|
||||||
@@ -31626,7 +31606,6 @@ function cbcTag(aad, iv, ciphertext, macSize, macKey, keySize) {
|
|||||||
hmac.update(macData);
|
hmac.update(macData);
|
||||||
return hmac.digest().slice(0, keySize >> 3);
|
return hmac.digest().slice(0, keySize >> 3);
|
||||||
}
|
}
|
||||||
exports["default"] = cbcTag;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -31848,6 +31827,7 @@ exports["default"] = digest;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports["default"] = dsaDigest;
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
function dsaDigest(alg) {
|
function dsaDigest(alg) {
|
||||||
switch (alg) {
|
switch (alg) {
|
||||||
@@ -31870,7 +31850,6 @@ function dsaDigest(alg) {
|
|||||||
throw new errors_js_1.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
throw new errors_js_1.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports["default"] = dsaDigest;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -31881,7 +31860,9 @@ exports["default"] = dsaDigest;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.ecdhAllowed = exports.generateEpk = exports.deriveKey = void 0;
|
exports.ecdhAllowed = void 0;
|
||||||
|
exports.deriveKey = deriveKey;
|
||||||
|
exports.generateEpk = generateEpk;
|
||||||
const node_crypto_1 = __nccwpck_require__(77598);
|
const node_crypto_1 = __nccwpck_require__(77598);
|
||||||
const node_util_1 = __nccwpck_require__(57975);
|
const node_util_1 = __nccwpck_require__(57975);
|
||||||
const get_named_curve_js_1 = __nccwpck_require__(65661);
|
const get_named_curve_js_1 = __nccwpck_require__(65661);
|
||||||
@@ -31920,7 +31901,6 @@ async function deriveKey(publicKee, privateKee, algorithm, keyLength, apu = new
|
|||||||
const sharedSecret = (0, node_crypto_1.diffieHellman)({ privateKey, publicKey });
|
const sharedSecret = (0, node_crypto_1.diffieHellman)({ privateKey, publicKey });
|
||||||
return (0, buffer_utils_js_1.concatKdf)(sharedSecret, keyLength, value);
|
return (0, buffer_utils_js_1.concatKdf)(sharedSecret, keyLength, value);
|
||||||
}
|
}
|
||||||
exports.deriveKey = deriveKey;
|
|
||||||
async function generateEpk(kee) {
|
async function generateEpk(kee) {
|
||||||
let key;
|
let key;
|
||||||
if ((0, webcrypto_js_1.isCryptoKey)(kee)) {
|
if ((0, webcrypto_js_1.isCryptoKey)(kee)) {
|
||||||
@@ -31946,7 +31926,6 @@ async function generateEpk(kee) {
|
|||||||
throw new errors_js_1.JOSENotSupported('Invalid or unsupported EPK');
|
throw new errors_js_1.JOSENotSupported('Invalid or unsupported EPK');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.generateEpk = generateEpk;
|
|
||||||
const ecdhAllowed = (key) => ['P-256', 'P-384', 'P-521', 'X25519', 'X448'].includes((0, get_named_curve_js_1.default)(key));
|
const ecdhAllowed = (key) => ['P-256', 'P-384', 'P-521', 'X25519', 'X448'].includes((0, get_named_curve_js_1.default)(key));
|
||||||
exports.ecdhAllowed = ecdhAllowed;
|
exports.ecdhAllowed = ecdhAllowed;
|
||||||
|
|
||||||
@@ -32100,7 +32079,8 @@ exports["default"] = fetchJwks;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.generateKeyPair = exports.generateSecret = void 0;
|
exports.generateSecret = generateSecret;
|
||||||
|
exports.generateKeyPair = generateKeyPair;
|
||||||
const node_crypto_1 = __nccwpck_require__(77598);
|
const node_crypto_1 = __nccwpck_require__(77598);
|
||||||
const node_util_1 = __nccwpck_require__(57975);
|
const node_util_1 = __nccwpck_require__(57975);
|
||||||
const random_js_1 = __nccwpck_require__(23376);
|
const random_js_1 = __nccwpck_require__(23376);
|
||||||
@@ -32133,7 +32113,6 @@ async function generateSecret(alg, options) {
|
|||||||
}
|
}
|
||||||
return (0, node_crypto_1.createSecretKey)((0, random_js_1.default)(new Uint8Array(length >> 3)));
|
return (0, node_crypto_1.createSecretKey)((0, random_js_1.default)(new Uint8Array(length >> 3)));
|
||||||
}
|
}
|
||||||
exports.generateSecret = generateSecret;
|
|
||||||
async function generateKeyPair(alg, options) {
|
async function generateKeyPair(alg, options) {
|
||||||
switch (alg) {
|
switch (alg) {
|
||||||
case 'RS256':
|
case 'RS256':
|
||||||
@@ -32199,7 +32178,6 @@ async function generateKeyPair(alg, options) {
|
|||||||
throw new errors_js_1.JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
throw new errors_js_1.JOSENotSupported('Invalid or unsupported JWK "alg" (Algorithm) Parameter value');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.generateKeyPair = generateKeyPair;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -32279,6 +32257,7 @@ exports["default"] = getNamedCurve;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports["default"] = getSignVerifyKey;
|
||||||
const node_crypto_1 = __nccwpck_require__(77598);
|
const node_crypto_1 = __nccwpck_require__(77598);
|
||||||
const webcrypto_js_1 = __nccwpck_require__(59044);
|
const webcrypto_js_1 = __nccwpck_require__(59044);
|
||||||
const crypto_key_js_1 = __nccwpck_require__(26319);
|
const crypto_key_js_1 = __nccwpck_require__(26319);
|
||||||
@@ -32307,7 +32286,6 @@ function getSignVerifyKey(alg, key, usage) {
|
|||||||
}
|
}
|
||||||
throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types, 'Uint8Array', 'JSON Web Key'));
|
throw new TypeError((0, invalid_key_input_js_1.default)(key, ...is_key_like_js_1.types, 'Uint8Array', 'JSON Web Key'));
|
||||||
}
|
}
|
||||||
exports["default"] = getSignVerifyKey;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -32318,6 +32296,7 @@ exports["default"] = getSignVerifyKey;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports["default"] = hmacDigest;
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
function hmacDigest(alg) {
|
function hmacDigest(alg) {
|
||||||
switch (alg) {
|
switch (alg) {
|
||||||
@@ -32331,7 +32310,6 @@ function hmacDigest(alg) {
|
|||||||
throw new errors_js_1.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
throw new errors_js_1.JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports["default"] = hmacDigest;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -32435,6 +32413,7 @@ exports["default"] = keyToJWK;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
|
exports["default"] = keyForCrypto;
|
||||||
const node_crypto_1 = __nccwpck_require__(77598);
|
const node_crypto_1 = __nccwpck_require__(77598);
|
||||||
const get_named_curve_js_1 = __nccwpck_require__(65661);
|
const get_named_curve_js_1 = __nccwpck_require__(65661);
|
||||||
const errors_js_1 = __nccwpck_require__(15974);
|
const errors_js_1 = __nccwpck_require__(15974);
|
||||||
@@ -32538,7 +32517,6 @@ function keyForCrypto(alg, key) {
|
|||||||
}
|
}
|
||||||
return options ? { ...options, key } : key;
|
return options ? { ...options, key } : key;
|
||||||
}
|
}
|
||||||
exports["default"] = keyForCrypto;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -32829,7 +32807,7 @@ exports.decode = base64url.decode;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.decodeJwt = void 0;
|
exports.decodeJwt = decodeJwt;
|
||||||
const base64url_js_1 = __nccwpck_require__(78305);
|
const base64url_js_1 = __nccwpck_require__(78305);
|
||||||
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
||||||
const is_object_js_1 = __nccwpck_require__(92242);
|
const is_object_js_1 = __nccwpck_require__(92242);
|
||||||
@@ -32862,7 +32840,6 @@ function decodeJwt(jwt) {
|
|||||||
throw new errors_js_1.JWTInvalid('Invalid JWT Claims Set');
|
throw new errors_js_1.JWTInvalid('Invalid JWT Claims Set');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
exports.decodeJwt = decodeJwt;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -32873,7 +32850,7 @@ exports.decodeJwt = decodeJwt;
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.decodeProtectedHeader = void 0;
|
exports.decodeProtectedHeader = decodeProtectedHeader;
|
||||||
const base64url_js_1 = __nccwpck_require__(78305);
|
const base64url_js_1 = __nccwpck_require__(78305);
|
||||||
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
const buffer_utils_js_1 = __nccwpck_require__(45734);
|
||||||
const is_object_js_1 = __nccwpck_require__(92242);
|
const is_object_js_1 = __nccwpck_require__(92242);
|
||||||
@@ -32908,7 +32885,6 @@ function decodeProtectedHeader(token) {
|
|||||||
throw new TypeError('Invalid Token or Protected Header formatting');
|
throw new TypeError('Invalid Token or Protected Header formatting');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.decodeProtectedHeader = decodeProtectedHeader;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@@ -70859,6 +70835,7 @@ const inputs = {
|
|||||||
subjectPath: core.getInput('subject-path'),
|
subjectPath: core.getInput('subject-path'),
|
||||||
subjectName: core.getInput('subject-name'),
|
subjectName: core.getInput('subject-name'),
|
||||||
subjectDigest: core.getInput('subject-digest'),
|
subjectDigest: core.getInput('subject-digest'),
|
||||||
|
subjectChecksums: core.getInput('subject-checksums'),
|
||||||
predicateType: core.getInput('predicate-type'),
|
predicateType: core.getInput('predicate-type'),
|
||||||
predicate: core.getInput('predicate'),
|
predicate: core.getInput('predicate'),
|
||||||
predicatePath: core.getInput('predicate-path'),
|
predicatePath: core.getInput('predicate-path'),
|
||||||
@@ -70868,7 +70845,7 @@ const inputs = {
|
|||||||
// undocumented -- not part of public interface
|
// undocumented -- not part of public interface
|
||||||
privateSigning: ['true', 'True', 'TRUE', '1'].includes(core.getInput('private-signing'))
|
privateSigning: ['true', 'True', 'TRUE', '1'].includes(core.getInput('private-signing'))
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
|
||||||
(0, main_1.run)(inputs);
|
(0, main_1.run)(inputs);
|
||||||
|
|
||||||
|
|
||||||
@@ -70975,7 +70952,7 @@ async function run(inputs) {
|
|||||||
core.setOutput('attestation-url', attestationURL(att.attestationID));
|
core.setOutput('attestation-url', attestationURL(att.attestationID));
|
||||||
}
|
}
|
||||||
if (inputs.showSummary) {
|
if (inputs.showSummary) {
|
||||||
logSummary(att);
|
await logSummary(att);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
@@ -71018,13 +70995,13 @@ const logAttestation = (subjects, attestation, sigstoreInstance) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Attach summary information to the GitHub Actions run
|
// Attach summary information to the GitHub Actions run
|
||||||
const logSummary = (attestation) => {
|
const logSummary = async (attestation) => {
|
||||||
const { attestationID } = attestation;
|
const { attestationID } = attestation;
|
||||||
if (attestationID) {
|
if (attestationID) {
|
||||||
const url = attestationURL(attestationID);
|
const url = attestationURL(attestationID);
|
||||||
core.summary.addHeading('Attestation Created', 3);
|
core.summary.addHeading('Attestation Created', 3);
|
||||||
core.summary.addList([`<a href="${url}">${url}</a>`]);
|
core.summary.addList([`<a href="${url}">${url}</a>`]);
|
||||||
core.summary.write();
|
await core.summary.write();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const tempDir = () => {
|
const tempDir = () => {
|
||||||
@@ -71153,23 +71130,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.formatSubjectDigest = exports.subjectFromInputs = void 0;
|
exports.formatSubjectDigest = exports.subjectFromInputs = void 0;
|
||||||
const glob = __importStar(__nccwpck_require__(47206));
|
const glob = __importStar(__nccwpck_require__(47206));
|
||||||
|
const assert_1 = __importDefault(__nccwpck_require__(42613));
|
||||||
const crypto_1 = __importDefault(__nccwpck_require__(76982));
|
const crypto_1 = __importDefault(__nccwpck_require__(76982));
|
||||||
const sync_1 = __nccwpck_require__(61110);
|
const sync_1 = __nccwpck_require__(61110);
|
||||||
const fs_1 = __importDefault(__nccwpck_require__(79896));
|
const fs_1 = __importDefault(__nccwpck_require__(79896));
|
||||||
|
const os_1 = __importDefault(__nccwpck_require__(70857));
|
||||||
const path_1 = __importDefault(__nccwpck_require__(16928));
|
const path_1 = __importDefault(__nccwpck_require__(16928));
|
||||||
const MAX_SUBJECT_COUNT = 1024;
|
const MAX_SUBJECT_COUNT = 1024;
|
||||||
|
const MAX_SUBJECT_CHECKSUM_SIZE_BYTES = 512 * MAX_SUBJECT_COUNT;
|
||||||
const DIGEST_ALGORITHM = 'sha256';
|
const DIGEST_ALGORITHM = 'sha256';
|
||||||
|
const HEX_STRING_RE = /^[0-9a-fA-F]+$/;
|
||||||
// Returns the subject specified by the action's inputs. The subject may be
|
// Returns the subject specified by the action's inputs. The subject may be
|
||||||
// specified as a path to a file or as a digest. If a path is provided, the
|
// specified as a path to a file or as a digest. If a path is provided, the
|
||||||
// file's digest is calculated and returned along with the subject's name. If a
|
// file's digest is calculated and returned along with the subject's name. If a
|
||||||
// digest is provided, the name must also be provided.
|
// digest is provided, the name must also be provided.
|
||||||
const subjectFromInputs = async (inputs) => {
|
const subjectFromInputs = async (inputs) => {
|
||||||
const { subjectPath, subjectDigest, subjectName, downcaseName } = inputs;
|
const { subjectPath, subjectDigest, subjectName, subjectChecksums, downcaseName } = inputs;
|
||||||
if (!subjectPath && !subjectDigest) {
|
const enabledInputs = [subjectPath, subjectDigest, subjectChecksums].filter(Boolean);
|
||||||
throw new Error('One of subject-path or subject-digest must be provided');
|
if (enabledInputs.length === 0) {
|
||||||
|
throw new Error('One of subject-path, subject-digest, or subject-checksums must be provided');
|
||||||
}
|
}
|
||||||
if (subjectPath && subjectDigest) {
|
if (enabledInputs.length > 1) {
|
||||||
throw new Error('Only one of subject-path or subject-digest may be provided');
|
throw new Error('Only one of subject-path, subject-digest, or subject-checksums may be provided');
|
||||||
}
|
}
|
||||||
if (subjectDigest && !subjectName) {
|
if (subjectDigest && !subjectName) {
|
||||||
throw new Error('subject-name must be provided when using subject-digest');
|
throw new Error('subject-name must be provided when using subject-digest');
|
||||||
@@ -71177,11 +71159,17 @@ const subjectFromInputs = async (inputs) => {
|
|||||||
// If push-to-registry is enabled, ensure the subject name is lowercase
|
// If push-to-registry is enabled, ensure the subject name is lowercase
|
||||||
// to conform to OCI image naming conventions
|
// to conform to OCI image naming conventions
|
||||||
const name = downcaseName ? subjectName.toLowerCase() : subjectName;
|
const name = downcaseName ? subjectName.toLowerCase() : subjectName;
|
||||||
if (subjectPath) {
|
switch (true) {
|
||||||
return await getSubjectFromPath(subjectPath, name);
|
case !!subjectPath:
|
||||||
}
|
return getSubjectFromPath(subjectPath, name);
|
||||||
else {
|
case !!subjectDigest:
|
||||||
return [getSubjectFromDigest(subjectDigest, name)];
|
return [getSubjectFromDigest(subjectDigest, name)];
|
||||||
|
case !!subjectChecksums:
|
||||||
|
return getSubjectFromChecksums(subjectChecksums);
|
||||||
|
/* istanbul ignore next */
|
||||||
|
default:
|
||||||
|
// This should be unreachable, but TS requires a default case
|
||||||
|
assert_1.default.fail('unreachable');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
exports.subjectFromInputs = subjectFromInputs;
|
exports.subjectFromInputs = subjectFromInputs;
|
||||||
@@ -71197,9 +71185,8 @@ exports.formatSubjectDigest = formatSubjectDigest;
|
|||||||
const getSubjectFromPath = async (subjectPath, subjectName) => {
|
const getSubjectFromPath = async (subjectPath, subjectName) => {
|
||||||
const digestedSubjects = [];
|
const digestedSubjects = [];
|
||||||
// Parse the list of subject paths
|
// Parse the list of subject paths
|
||||||
const subjectPaths = parseList(subjectPath).join('\n');
|
const subjectPaths = parseSubjectPathList(subjectPath).join('\n');
|
||||||
// Expand the globbed paths to a list of actual paths
|
// Expand the globbed paths to a list of actual paths
|
||||||
/* eslint-disable-next-line github/no-then */
|
|
||||||
const paths = await glob.create(subjectPaths).then(async (g) => g.glob());
|
const paths = await glob.create(subjectPaths).then(async (g) => g.glob());
|
||||||
// Filter path list to just the files (not directories)
|
// Filter path list to just the files (not directories)
|
||||||
const files = paths.filter(p => fs_1.default.statSync(p).isFile());
|
const files = paths.filter(p => fs_1.default.statSync(p).isFile());
|
||||||
@@ -71231,6 +71218,49 @@ const getSubjectFromDigest = (subjectDigest, subjectName) => {
|
|||||||
digest: { [alg]: digest }
|
digest: { [alg]: digest }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
const getSubjectFromChecksums = (subjectChecksums) => {
|
||||||
|
if (fs_1.default.existsSync(subjectChecksums)) {
|
||||||
|
return getSubjectFromChecksumsFile(subjectChecksums);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getSubjectFromChecksumsString(subjectChecksums);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const getSubjectFromChecksumsFile = (checksumsPath) => {
|
||||||
|
const stats = fs_1.default.statSync(checksumsPath);
|
||||||
|
if (!stats.isFile()) {
|
||||||
|
throw new Error(`subject checksums file not found: ${checksumsPath}`);
|
||||||
|
}
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (stats.size > MAX_SUBJECT_CHECKSUM_SIZE_BYTES) {
|
||||||
|
throw new Error(`subject checksums file exceeds maximum allowed size: ${MAX_SUBJECT_CHECKSUM_SIZE_BYTES} bytes`);
|
||||||
|
}
|
||||||
|
const checksums = fs_1.default.readFileSync(checksumsPath, 'utf-8');
|
||||||
|
return getSubjectFromChecksumsString(checksums);
|
||||||
|
};
|
||||||
|
const getSubjectFromChecksumsString = (checksums) => {
|
||||||
|
const subjects = [];
|
||||||
|
const records = checksums.split(os_1.default.EOL).filter(Boolean);
|
||||||
|
for (const record of records) {
|
||||||
|
// Find the space delimiter following the digest
|
||||||
|
const delimIndex = record.indexOf(' ');
|
||||||
|
// Skip any line that doesn't have a delimiter
|
||||||
|
if (delimIndex === -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Swallow the type identifier character at the beginning of the name
|
||||||
|
const name = record.slice(delimIndex + 2);
|
||||||
|
const digest = record.slice(0, delimIndex);
|
||||||
|
if (!HEX_STRING_RE.test(digest)) {
|
||||||
|
throw new Error(`Invalid digest: ${digest}`);
|
||||||
|
}
|
||||||
|
subjects.push({
|
||||||
|
name,
|
||||||
|
digest: { [digestAlgorithm(digest)]: digest }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return subjects;
|
||||||
|
};
|
||||||
// Calculates the digest of a file using the specified algorithm. The file is
|
// Calculates the digest of a file using the specified algorithm. The file is
|
||||||
// streamed into the digest function to avoid loading the entire file into
|
// streamed into the digest function to avoid loading the entire file into
|
||||||
// memory. The returned digest is a hex string.
|
// memory. The returned digest is a hex string.
|
||||||
@@ -71243,7 +71273,7 @@ const digestFile = async (algorithm, filePath) => {
|
|||||||
.once('finish', () => resolve(hash.read()));
|
.once('finish', () => resolve(hash.read()));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const parseList = (input) => {
|
const parseSubjectPathList = (input) => {
|
||||||
const res = [];
|
const res = [];
|
||||||
const records = (0, sync_1.parse)(input, {
|
const records = (0, sync_1.parse)(input, {
|
||||||
columns: false,
|
columns: false,
|
||||||
@@ -71256,6 +71286,16 @@ const parseList = (input) => {
|
|||||||
}
|
}
|
||||||
return res.filter(item => item).map(pat => pat.trim());
|
return res.filter(item => item).map(pat => pat.trim());
|
||||||
};
|
};
|
||||||
|
const digestAlgorithm = (digest) => {
|
||||||
|
switch (digest.length) {
|
||||||
|
case 64:
|
||||||
|
return 'sha256';
|
||||||
|
case 128:
|
||||||
|
return 'sha512';
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown digest algorithm: ${digest}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|||||||
4018
package-lock.json
generated
4018
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "actions/attest",
|
"name": "actions/attest",
|
||||||
"description": "Generate signed attestations for workflow artifacts",
|
"description": "Generate signed attestations for workflow artifacts",
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/actions/attest",
|
"homepage": "https://github.com/actions/attest",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"ci-test": "jest",
|
"ci-test": "jest",
|
||||||
"format:write": "prettier --write **/*.ts",
|
"format:write": "prettier --write **/*.ts",
|
||||||
"format:check": "prettier --check **/*.ts",
|
"format:check": "prettier --check **/*.ts",
|
||||||
"lint:eslint": "npx eslint . -c ./.github/linters/.eslintrc.yml",
|
"lint:eslint": "npx eslint . -c ./.github/linters/eslint.config.mjs",
|
||||||
"lint:markdown": "npx markdownlint --config .github/linters/.markdown-lint.yml \"*.md\"",
|
"lint:markdown": "npx markdownlint --config .github/linters/.markdown-lint.yml \"*.md\"",
|
||||||
"lint": "npm run lint:eslint && npm run lint:markdown",
|
"lint": "npm run lint:eslint && npm run lint:markdown",
|
||||||
"package": "ncc build src/index.ts --license licenses.txt",
|
"package": "ncc build src/index.ts --license licenses.txt",
|
||||||
@@ -71,31 +71,29 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/attest": "^1.5.0",
|
"@actions/attest": "^1.5.0",
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^1.11.1",
|
||||||
|
"@actions/github": "^6.0.0",
|
||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.5.0",
|
||||||
"@sigstore/oci": "^0.4.0",
|
"@sigstore/oci": "^0.4.0",
|
||||||
"csv-parse": "^5.6.0"
|
"csv-parse": "^5.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sigstore/mock": "^0.8.0",
|
"@eslint/js": "^9.18.0",
|
||||||
|
"@sigstore/mock": "^0.9.0",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/make-fetch-happen": "^10.0.4",
|
"@types/make-fetch-happen": "^10.0.4",
|
||||||
"@types/node": "^22.9.4",
|
"@types/node": "^22.10.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
||||||
"@typescript-eslint/parser": "^7.18.0",
|
|
||||||
"@vercel/ncc": "^0.38.3",
|
"@vercel/ncc": "^0.38.3",
|
||||||
"eslint": "^8.57.1",
|
"eslint": "^9.18.0",
|
||||||
"eslint-plugin-github": "^5.1.2",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
"eslint-plugin-jest": "^28.9.0",
|
"eslint-plugin-jest": "^28.11.0",
|
||||||
"eslint-plugin-jsonc": "^2.18.2",
|
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"markdownlint-cli": "^0.43.0",
|
"markdownlint-cli": "^0.43.0",
|
||||||
"nock": "^13.5.6",
|
"nock": "^13.5.6",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.4.2",
|
||||||
"prettier-eslint": "^16.3.0",
|
|
||||||
"ts-jest": "^29.2.5",
|
"ts-jest": "^29.2.5",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.3",
|
||||||
|
"typescript-eslint": "^8.21.0",
|
||||||
"undici": "^5.28.4"
|
"undici": "^5.28.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const inputs: RunInputs = {
|
|||||||
subjectPath: core.getInput('subject-path'),
|
subjectPath: core.getInput('subject-path'),
|
||||||
subjectName: core.getInput('subject-name'),
|
subjectName: core.getInput('subject-name'),
|
||||||
subjectDigest: core.getInput('subject-digest'),
|
subjectDigest: core.getInput('subject-digest'),
|
||||||
|
subjectChecksums: core.getInput('subject-checksums'),
|
||||||
predicateType: core.getInput('predicate-type'),
|
predicateType: core.getInput('predicate-type'),
|
||||||
predicate: core.getInput('predicate'),
|
predicate: core.getInput('predicate'),
|
||||||
predicatePath: core.getInput('predicate-path'),
|
predicatePath: core.getInput('predicate-path'),
|
||||||
@@ -20,5 +21,5 @@ const inputs: RunInputs = {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
|
||||||
run(inputs)
|
run(inputs)
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export async function run(inputs: RunInputs): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (inputs.showSummary) {
|
if (inputs.showSummary) {
|
||||||
logSummary(att)
|
await logSummary(att)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Fail the workflow run if an error occurs
|
// Fail the workflow run if an error occurs
|
||||||
@@ -153,14 +153,14 @@ const logAttestation = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attach summary information to the GitHub Actions run
|
// Attach summary information to the GitHub Actions run
|
||||||
const logSummary = (attestation: AttestResult): void => {
|
const logSummary = async (attestation: AttestResult): Promise<void> => {
|
||||||
const { attestationID } = attestation
|
const { attestationID } = attestation
|
||||||
|
|
||||||
if (attestationID) {
|
if (attestationID) {
|
||||||
const url = attestationURL(attestationID)
|
const url = attestationURL(attestationID)
|
||||||
core.summary.addHeading('Attestation Created', 3)
|
core.summary.addHeading('Attestation Created', 3)
|
||||||
core.summary.addList([`<a href="${url}">${url}</a>`])
|
core.summary.addList([`<a href="${url}">${url}</a>`])
|
||||||
core.summary.write()
|
await core.summary.write()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
113
src/subject.ts
113
src/subject.ts
@@ -1,18 +1,23 @@
|
|||||||
import * as glob from '@actions/glob'
|
import * as glob from '@actions/glob'
|
||||||
|
import assert from 'assert'
|
||||||
import crypto from 'crypto'
|
import crypto from 'crypto'
|
||||||
import { parse } from 'csv-parse/sync'
|
import { parse } from 'csv-parse/sync'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import os from 'os'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
import type { Subject } from '@actions/attest'
|
import type { Subject } from '@actions/attest'
|
||||||
|
|
||||||
const MAX_SUBJECT_COUNT = 1024
|
const MAX_SUBJECT_COUNT = 1024
|
||||||
|
const MAX_SUBJECT_CHECKSUM_SIZE_BYTES = 512 * MAX_SUBJECT_COUNT
|
||||||
const DIGEST_ALGORITHM = 'sha256'
|
const DIGEST_ALGORITHM = 'sha256'
|
||||||
|
const HEX_STRING_RE = /^[0-9a-fA-F]+$/
|
||||||
|
|
||||||
export type SubjectInputs = {
|
export type SubjectInputs = {
|
||||||
subjectPath: string
|
subjectPath: string
|
||||||
subjectName: string
|
subjectName: string
|
||||||
subjectDigest: string
|
subjectDigest: string
|
||||||
|
subjectChecksums: string
|
||||||
downcaseName?: boolean
|
downcaseName?: boolean
|
||||||
}
|
}
|
||||||
// Returns the subject specified by the action's inputs. The subject may be
|
// Returns the subject specified by the action's inputs. The subject may be
|
||||||
@@ -22,15 +27,26 @@ export type SubjectInputs = {
|
|||||||
export const subjectFromInputs = async (
|
export const subjectFromInputs = async (
|
||||||
inputs: SubjectInputs
|
inputs: SubjectInputs
|
||||||
): Promise<Subject[]> => {
|
): Promise<Subject[]> => {
|
||||||
const { subjectPath, subjectDigest, subjectName, downcaseName } = inputs
|
const {
|
||||||
|
subjectPath,
|
||||||
|
subjectDigest,
|
||||||
|
subjectName,
|
||||||
|
subjectChecksums,
|
||||||
|
downcaseName
|
||||||
|
} = inputs
|
||||||
|
|
||||||
if (!subjectPath && !subjectDigest) {
|
const enabledInputs = [subjectPath, subjectDigest, subjectChecksums].filter(
|
||||||
throw new Error('One of subject-path or subject-digest must be provided')
|
Boolean
|
||||||
|
)
|
||||||
|
if (enabledInputs.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
'One of subject-path, subject-digest, or subject-checksums must be provided'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subjectPath && subjectDigest) {
|
if (enabledInputs.length > 1) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Only one of subject-path or subject-digest may be provided'
|
'Only one of subject-path, subject-digest, or subject-checksums may be provided'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +58,17 @@ export const subjectFromInputs = async (
|
|||||||
// to conform to OCI image naming conventions
|
// to conform to OCI image naming conventions
|
||||||
const name = downcaseName ? subjectName.toLowerCase() : subjectName
|
const name = downcaseName ? subjectName.toLowerCase() : subjectName
|
||||||
|
|
||||||
if (subjectPath) {
|
switch (true) {
|
||||||
return await getSubjectFromPath(subjectPath, name)
|
case !!subjectPath:
|
||||||
} else {
|
return getSubjectFromPath(subjectPath, name)
|
||||||
return [getSubjectFromDigest(subjectDigest, name)]
|
case !!subjectDigest:
|
||||||
|
return [getSubjectFromDigest(subjectDigest, name)]
|
||||||
|
case !!subjectChecksums:
|
||||||
|
return getSubjectFromChecksums(subjectChecksums)
|
||||||
|
/* istanbul ignore next */
|
||||||
|
default:
|
||||||
|
// This should be unreachable, but TS requires a default case
|
||||||
|
assert.fail('unreachable')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,10 +88,9 @@ const getSubjectFromPath = async (
|
|||||||
const digestedSubjects: Subject[] = []
|
const digestedSubjects: Subject[] = []
|
||||||
|
|
||||||
// Parse the list of subject paths
|
// Parse the list of subject paths
|
||||||
const subjectPaths = parseList(subjectPath).join('\n')
|
const subjectPaths = parseSubjectPathList(subjectPath).join('\n')
|
||||||
|
|
||||||
// Expand the globbed paths to a list of actual paths
|
// Expand the globbed paths to a list of actual paths
|
||||||
/* eslint-disable-next-line github/no-then */
|
|
||||||
const paths = await glob.create(subjectPaths).then(async g => g.glob())
|
const paths = await glob.create(subjectPaths).then(async g => g.glob())
|
||||||
|
|
||||||
// Filter path list to just the files (not directories)
|
// Filter path list to just the files (not directories)
|
||||||
@@ -120,6 +142,62 @@ const getSubjectFromDigest = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getSubjectFromChecksums = (subjectChecksums: string): Subject[] => {
|
||||||
|
if (fs.existsSync(subjectChecksums)) {
|
||||||
|
return getSubjectFromChecksumsFile(subjectChecksums)
|
||||||
|
} else {
|
||||||
|
return getSubjectFromChecksumsString(subjectChecksums)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSubjectFromChecksumsFile = (checksumsPath: string): Subject[] => {
|
||||||
|
const stats = fs.statSync(checksumsPath)
|
||||||
|
if (!stats.isFile()) {
|
||||||
|
throw new Error(`subject checksums file not found: ${checksumsPath}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (stats.size > MAX_SUBJECT_CHECKSUM_SIZE_BYTES) {
|
||||||
|
throw new Error(
|
||||||
|
`subject checksums file exceeds maximum allowed size: ${MAX_SUBJECT_CHECKSUM_SIZE_BYTES} bytes`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const checksums = fs.readFileSync(checksumsPath, 'utf-8')
|
||||||
|
return getSubjectFromChecksumsString(checksums)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSubjectFromChecksumsString = (checksums: string): Subject[] => {
|
||||||
|
const subjects: Subject[] = []
|
||||||
|
|
||||||
|
const records: string[] = checksums.split(os.EOL).filter(Boolean)
|
||||||
|
|
||||||
|
for (const record of records) {
|
||||||
|
// Find the space delimiter following the digest
|
||||||
|
const delimIndex = record.indexOf(' ')
|
||||||
|
|
||||||
|
// Skip any line that doesn't have a delimiter
|
||||||
|
if (delimIndex === -1) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swallow the type identifier character at the beginning of the name
|
||||||
|
const name = record.slice(delimIndex + 2)
|
||||||
|
const digest = record.slice(0, delimIndex)
|
||||||
|
|
||||||
|
if (!HEX_STRING_RE.test(digest)) {
|
||||||
|
throw new Error(`Invalid digest: ${digest}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
subjects.push({
|
||||||
|
name,
|
||||||
|
digest: { [digestAlgorithm(digest)]: digest }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return subjects
|
||||||
|
}
|
||||||
|
|
||||||
// Calculates the digest of a file using the specified algorithm. The file is
|
// Calculates the digest of a file using the specified algorithm. The file is
|
||||||
// streamed into the digest function to avoid loading the entire file into
|
// streamed into the digest function to avoid loading the entire file into
|
||||||
// memory. The returned digest is a hex string.
|
// memory. The returned digest is a hex string.
|
||||||
@@ -136,7 +214,7 @@ const digestFile = async (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseList = (input: string): string[] => {
|
const parseSubjectPathList = (input: string): string[] => {
|
||||||
const res: string[] = []
|
const res: string[] = []
|
||||||
|
|
||||||
const records: string[][] = parse(input, {
|
const records: string[][] = parse(input, {
|
||||||
@@ -152,3 +230,14 @@ const parseList = (input: string): string[] => {
|
|||||||
|
|
||||||
return res.filter(item => item).map(pat => pat.trim())
|
return res.filter(item => item).map(pat => pat.trim())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const digestAlgorithm = (digest: string): string => {
|
||||||
|
switch (digest.length) {
|
||||||
|
case 64:
|
||||||
|
return 'sha256'
|
||||||
|
case 128:
|
||||||
|
return 'sha512'
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown digest algorithm: ${digest}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user