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.List; 020import java.util.Objects; 021 022import com.fasterxml.jackson.annotation.JsonProperty; 023 024/** 025 * In-toto v1 attestation envelope that binds a set of subject artifacts to an SLSA provenance predicate. 026 * 027 * @see <a href="https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md">in-toto Statement v1</a> 028 * @since 1.10.0 029 */ 030public class Statement { 031 032 /** The in-toto statement schema URI. */ 033 public static final String TYPE = "https://in-toto.io/Statement/v1"; 034 /** The provenance predicate. */ 035 @JsonProperty("predicate") 036 private Provenance predicate; 037 /** URI identifying the type of the predicate. */ 038 @JsonProperty("predicateType") 039 private String predicateType; 040 /** Software artifacts that the attestation applies to. */ 041 @JsonProperty("subject") 042 private List<ResourceDescriptor> subject; 043 044 /** Creates a new Statement instance. */ 045 public Statement() { 046 } 047 048 @Override 049 public boolean equals(final Object o) { 050 if (!(o instanceof Statement)) { 051 return false; 052 } 053 final Statement statement = (Statement) o; 054 return Objects.equals(subject, statement.subject) && Objects.equals(predicateType, statement.predicateType) && Objects.equals(predicate, 055 statement.predicate); 056 } 057 058 /** 059 * Gets the JSON object type. 060 * 061 * @return Always {@value #TYPE}. 062 */ 063 @JsonProperty("_type") 064 public String getType() { 065 return TYPE; 066 } 067 068 /** 069 * Gets the provenance predicate. 070 * 071 * <p> 072 * An unset predicate is treated the same as an empty predicate. The predicate may be omitted if {@code predicateType} fully describes the 073 * predicate. 074 * </p> 075 * 076 * @return The provenance predicate, or {@code null} if not set. 077 */ 078 public Provenance getPredicate() { 079 return predicate; 080 } 081 082 /** 083 * Gets the URI identifying the type of the predicate. 084 * 085 * @return The predicate type URI, or {@code null} if no predicate has been set. 086 */ 087 public String getPredicateType() { 088 return predicateType; 089 } 090 091 /** 092 * Gets the set of software artifacts that the attestation applies to. 093 * 094 * <p> 095 * Each element represents a single artifact. Artifacts are matched purely by digest, regardless of content type. 096 * </p> 097 * 098 * @return The list of subject artifacts, or {@code null} if not set. 099 */ 100 public List<ResourceDescriptor> getSubject() { 101 return subject; 102 } 103 104 @Override 105 public int hashCode() { 106 return Objects.hash(subject, predicateType, predicate); 107 } 108 109 /** 110 * Sets the provenance predicate and automatically assigns {@code predicateType} to the SLSA provenance v1 URI. 111 * 112 * @param predicate The provenance predicate. 113 * @return this for chaining. 114 */ 115 public Statement setPredicate(final Provenance predicate) { 116 this.predicate = predicate; 117 this.predicateType = Provenance.PREDICATE_TYPE; 118 return this; 119 } 120 121 /** 122 * Sets the set of software artifacts that the attestation applies to. 123 * 124 * @param subject The list of subject artifacts. 125 * @return this for chaining. 126 */ 127 public Statement setSubject(final List<ResourceDescriptor> subject) { 128 this.subject = subject; 129 return this; 130 } 131 132 @Override 133 public String toString() { 134 return "Statement{type='" + TYPE + "', subject=" + subject + ", predicateType='" + predicateType + "', predicate=" + predicate + '}'; 135 } 136}