001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.release.plugin.slsa.v1_2;
018
019import java.util.Arrays;
020import java.util.List;
021import java.util.Objects;
022
023import com.fasterxml.jackson.annotation.JsonProperty;
024import org.apache.commons.lang3.ArrayUtils;
025
026/**
027 * DSSE (Dead Simple Signing Envelope) that wraps a signed in-toto statement payload.
028 *
029 * @see <a href="https://github.com/secure-systems-lab/dsse/blob/v1.0.2/envelope.md">DSSE Envelope specification</a>
030 * @since 1.10.0
031 */
032public class DsseEnvelope {
033
034    /** The payload type URI for in-toto attestation statements. */
035    public static final String PAYLOAD_TYPE = "application/vnd.in-toto+json";
036    /** Serialized statement bytes, Base64-encoded in JSON. */
037    @JsonProperty("payload")
038    private byte[] payload;
039    /** Content type identifying the format of {@link #payload}. */
040    @JsonProperty("payloadType")
041    private String payloadType = PAYLOAD_TYPE;
042    /** One or more signatures over the PAE-encoded payload. */
043    @JsonProperty("signatures")
044    private List<Signature> signatures;
045
046    /** Creates a new DsseEnvelope instance with {@code payloadType} pre-set to {@link #PAYLOAD_TYPE}. */
047    public DsseEnvelope() {
048    }
049
050    @Override
051    public boolean equals(final Object o) {
052        if (!(o instanceof DsseEnvelope)) {
053            return false;
054        }
055        final DsseEnvelope envelope = (DsseEnvelope) o;
056        return Objects.equals(payloadType, envelope.payloadType) && Arrays.equals(payload, envelope.payload)
057                && Objects.equals(signatures, envelope.signatures);
058    }
059
060    /**
061     * Gets the serialized payload bytes.
062     *
063     * <p>
064     * When serialized to JSON, the bytes are Base64-encoded.
065     * </p>
066     *
067     * @return The payload bytes, or {@code null} if not set.
068     */
069    public byte[] getPayload() {
070        return payload;
071    }
072
073    /**
074     * Gets the payload type URI.
075     *
076     * @return The payload type, never {@code null} in a valid envelope.
077     */
078    public String getPayloadType() {
079        return payloadType;
080    }
081
082    /**
083     * Gets the list of signatures over the PAE-encoded payload.
084     *
085     * @return The signatures, or {@code null} if not set.
086     */
087    public List<Signature> getSignatures() {
088        return signatures;
089    }
090
091    @Override
092    public int hashCode() {
093        return Objects.hash(payloadType, Arrays.hashCode(payload), signatures);
094    }
095
096    /**
097     * Sets the serialized payload bytes.
098     *
099     * @param payload The payload bytes.
100     * @return this for chaining.
101     */
102    public DsseEnvelope setPayload(final byte[] payload) {
103        this.payload = payload;
104        return this;
105    }
106
107    /**
108     * Sets the payload type URI.
109     *
110     * @param payloadType The payload type URI.
111     * @return this for chaining.
112     */
113    public DsseEnvelope setPayloadType(final String payloadType) {
114        this.payloadType = payloadType;
115        return this;
116    }
117
118    /**
119     * Sets the list of signatures over the PAE-encoded payload.
120     *
121     * @param signatures The signatures.
122     * @return this for chaining.
123     */
124    public DsseEnvelope setSignatures(final List<Signature> signatures) {
125        this.signatures = signatures;
126        return this;
127    }
128
129    @Override
130    public String toString() {
131        return "DsseEnvelope{payloadType='" + payloadType
132                + "', payload=<" + ArrayUtils.getLength(payload)
133                + " bytes>, signatures=" + signatures + '}';
134    }
135}