Skip to content

Commit

Permalink
envelope serialization funcs in bundle pkg (#617)
Browse files Browse the repository at this point in the history
Signed-off-by: Brian DeHamer <bdehamer@github.com>
  • Loading branch information
bdehamer committed Jul 17, 2023
1 parent 335cb74 commit 2a869ba
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/swift-socks-knock.md
@@ -0,0 +1,5 @@
---
'@sigstore/bundle': minor
---

export `envelopeToJSON`/`envelopeFromJSON` functions for serialization/deserialization of DSSE envelopes
4 changes: 4 additions & 0 deletions packages/bundle/src/__tests__/index.test.ts
Expand Up @@ -45,6 +45,8 @@ import {
assertBundleV01,
bundleFromJSON,
bundleToJSON,
envelopeFromJSON,
envelopeToJSON,
isBundleV01,
isBundleWithCertificateChain,
isBundleWithDsseEnvelope,
Expand Down Expand Up @@ -144,6 +146,8 @@ describe('public interface', () => {
it('exports serialization functions', () => {
expect(bundleFromJSON).toBeDefined();
expect(bundleToJSON).toBeDefined();
expect(envelopeFromJSON).toBeDefined();
expect(envelopeToJSON).toBeDefined();
});

it('exports constants', () => {
Expand Down
48 changes: 47 additions & 1 deletion packages/bundle/src/__tests__/serialized.test.ts
Expand Up @@ -23,7 +23,12 @@ import {
X509CertificateChain,
hashAlgorithmToJSON,
} from '@sigstore/protobuf-specs';
import { bundleFromJSON, bundleToJSON } from '../serialized';
import {
bundleFromJSON,
bundleToJSON,
envelopeFromJSON,
envelopeToJSON,
} from '../serialized';

import type { Bundle } from '../bundle';

Expand Down Expand Up @@ -361,3 +366,44 @@ describe('bundleFromJSON', () => {
expect(deserializedBundle).toEqual(bundle);
});
});

describe('envelopeToJSON', () => {
const dsseEnvelope: Envelope = {
payload: Buffer.from('payload'),
payloadType: 'application/vnd.in-toto+json',
signatures: [
{
keyid: 'keyid',
sig: Buffer.from('signature'),
},
],
};

it('matches the serialized form of the Envelope', () => {
const json = envelopeToJSON(dsseEnvelope);

expect(json).toBeTruthy();
expect(json.payload).toEqual(dsseEnvelope.payload.toString('base64'));
expect(json.payloadType).toEqual(dsseEnvelope.payloadType);
expect(json.signatures).toHaveLength(dsseEnvelope.signatures.length);
const signature = json.signatures[0];
const expectedSignature = dsseEnvelope.signatures[0];
expect(signature).toBeTruthy();
expect(signature?.keyid).toEqual(expectedSignature.keyid);
expect(signature?.sig).toEqual(expectedSignature.sig.toString('base64'));
});
});

describe('envelopeFromJSON', () => {
const envelope = {
payload: Buffer.from('ABC'),
payloadType: 'application/json',
signatures: [{ sig: Buffer.from('BAR'), keyid: '' }],
};

it('matches the deserialized form of the Envelope', () => {
const json = envelopeToJSON(envelope);
const deserializedEnvelope = envelopeFromJSON(json);
expect(deserializedEnvelope).toEqual(envelope);
});
});
7 changes: 6 additions & 1 deletion packages/bundle/src/index.ts
Expand Up @@ -22,7 +22,12 @@ export {
isBundleWithPublicKey,
} from './bundle';
export { ValidationError } from './error';
export { bundleFromJSON, bundleToJSON } from './serialized';
export {
bundleFromJSON,
bundleToJSON,
envelopeFromJSON,
envelopeToJSON,
} from './serialized';
export {
assertBundle,
assertBundleLatest,
Expand Down
21 changes: 12 additions & 9 deletions packages/bundle/src/serialized.ts
Expand Up @@ -13,24 +13,30 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { Bundle as ProtoBundle } from '@sigstore/protobuf-specs';
import { Envelope, Bundle as ProtoBundle } from '@sigstore/protobuf-specs';
import { assertBundle } from './validate';

import type { Bundle } from './bundle';
import type { OneOf } from './utility';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const bundleFromJSON = (obj: any): Bundle => {
export const bundleFromJSON = (obj: unknown): Bundle => {
const bundle = ProtoBundle.fromJSON(obj);
assertBundle(bundle);
return bundle;
};

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const bundleToJSON = (bundle: Bundle): SerializedBundle => {
return ProtoBundle.toJSON(bundle) as SerializedBundle;
};

export const envelopeFromJSON = (obj: unknown): Envelope => {
return Envelope.fromJSON(obj);
};

export const envelopeToJSON = (envelope: Envelope): SerializedEnvelope => {
return Envelope.toJSON(envelope) as SerializedEnvelope;
};

type SerializedTLogEntry = {
logIndex: string;
logId: {
Expand Down Expand Up @@ -76,7 +82,7 @@ type SerializedMessageSignature = {
};

// Serialized form of the dsseEnvelope option in the Sigstore Bundle
type SerializedDSSEEnvelope = {
export type SerializedEnvelope = {
payload: string;
payloadType: string;
signatures: {
Expand All @@ -85,9 +91,6 @@ type SerializedDSSEEnvelope = {
}[];
};

// Serialized form of the DSSE Envelope
export type { SerializedDSSEEnvelope as SerializedEnvelope };

// Serialized form of the Sigstore Bundle union type with all possible options
// represented
export type SerializedBundle = {
Expand All @@ -103,6 +106,6 @@ export type SerializedBundle = {
timestampVerificationData: SerializedTimestampVerificationData | undefined;
};
} & OneOf<{
dsseEnvelope: SerializedDSSEEnvelope;
dsseEnvelope: SerializedEnvelope;
messageSignature: SerializedMessageSignature;
}>;

0 comments on commit 2a869ba

Please sign in to comment.