// Copyright 2022 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// 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.

syntax = "proto3";
package dev.sigstore.common.v1;

import "google/api/field_behavior.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/sigstore/protobuf-specs/gen/pb-go/common/v1";
option java_package = "dev.sigstore.proto.common.v1";
option java_multiple_files = true;
option java_outer_classname = "CommonProto";
option ruby_package = "Sigstore::Common::V1";

// This package defines commonly used message types within the Sigstore
// community.

// Only a subset of the secure hash standard algorithms are supported.
// See <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf> for more
// details.
// UNSPECIFIED SHOULD not be used, primary reason for inclusion is to force
// any proto JSON serialization to emit the used hash algorithm, as default
// option is to *omit* the default value of an enum (which is the first
// value, represented by '0'.
enum HashAlgorithm {
        HASH_ALGORITHM_UNSPECIFIED = 0;
        SHA2_256 = 1;
}

// Details of a specific public key, capturing the the key encoding method,
// and signature algorithm.
// To avoid the possibility of contradicting formats such as PKCS1 with
// ED25519 the valid permutations are listed as a linear set instead of a
// cartesian set (i.e one combined variable instead of two, one for encoding
// and one for the signature algorithm).
enum PublicKeyDetails {
        PUBLIC_KEY_DETAILS_UNSPECIFIED = 0;
        // RSA
        PKCS1_RSA_PKCS1V5 = 1; // See RFC8017
        PKCS1_RSA_PSS = 2; // See RFC8017
        PKIX_RSA_PKCS1V5 = 3;
        PKIX_RSA_PSS = 4;
        // ECDSA
        PKIX_ECDSA_P256_SHA_256 = 5; // See NIST FIPS 186-4
        PKIX_ECDSA_P256_HMAC_SHA_256 = 6; // See RFC6979
        // Ed 25519
        PKIX_ED25519 = 7; // See RFC8032
}

// HashOutput captures a digest of a 'message' (generic octet sequence)
// and the corresponding hash algorithm used.
message HashOutput {
        HashAlgorithm algorithm = 1;
        // This is the raw octets of the message digest as computed by
        // the hash algorithm.
        bytes digest = 2;
}

// MessageSignature stores the computed signature over a message.
message MessageSignature {
        // Message digest can be used to identify the artifact.
        // Clients MUST NOT attempt to use this digest to verify the associated
        // signature; it is intended solely for identification.
        HashOutput message_digest = 1;
        // The raw bytes as returned from the signature algorithm.
        // The signature algorithm (and so the format of the signature bytes)
        // are determined by the contents of the 'verification_material',
        // either a key-pair or a certificate. If using a certificate, the
        // certificate contains the required information on the signature
        // algorithm.
        // When using a key pair, the algorithm MUST be part of the public
        // key, which MUST be communicated out-of-band.
        bytes signature = 2 [(google.api.field_behavior) = REQUIRED];
}

// LogId captures the identity of a transparency log.
message LogId {
        // The unique id of the log, represented as the SHA-256 hash
        // of the log's public key, calculated over the DER encoding
        // of the key represented as SubjectPublicKeyInfo.
        // See https://www.rfc-editor.org/rfc/rfc6962#section-3.2
        bytes key_id = 1 [(google.api.field_behavior) = REQUIRED];
}

// This message holds a RFC 3161 timestamp.
message RFC3161SignedTimestamp {
        // Signed timestamp is the DER encoded TimeStampResponse.
        // See https://www.rfc-editor.org/rfc/rfc3161.html#section-2.4.2
        bytes signed_timestamp = 1 [(google.api.field_behavior) = REQUIRED];
}

message PublicKey {
        // DER-encoded public key, encoding method is specified by the
        // key_details attribute.
        optional bytes raw_bytes = 1;
        // Key encoding and signature algorithm to use for this key.
        PublicKeyDetails key_details = 2;
        // Optional validity period for this key, *inclusive* of the endpoints.
        optional TimeRange valid_for = 3;
}

// PublicKeyIdentifier can be used to identify an (out of band) delivered
// key, to verify a signature.
message PublicKeyIdentifier {
        // Optional unauthenticated hint on which key to use.
        // The format of the hint must be agreed upon out of band by the
        // signer and the verifiers, and so is not subject to this
        // specification.
        // Example use-case is to specify the public key to use, from a
        // trusted key-ring.
        // Implementors are RECOMMENDED to derive the value from the public
        // key as described in RFC 6962.
        // See: <https://www.rfc-editor.org/rfc/rfc6962#section-3.2>
        string hint = 1;
}

// An ASN.1 OBJECT IDENTIFIER
message ObjectIdentifier {
        repeated int32 id = 1 [(google.api.field_behavior) = REQUIRED];
}

// An OID and the corresponding (byte) value.
message ObjectIdentifierValuePair {
        ObjectIdentifier oid = 1;
        bytes value = 2;
}

message DistinguishedName {
        string organization = 1;
        string common_name = 2;
}

message X509Certificate {
        // DER-encoded X.509 certificate.
        bytes raw_bytes = 1 [(google.api.field_behavior) = REQUIRED];
}

enum SubjectAlternativeNameType {
        SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED = 0;
        EMAIL = 1;
        URI = 2;
        // OID 1.3.6.1.4.1.57264.1.7
        // See https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#1361415726417--othername-san
        // for more details.
        OTHER_NAME = 3;
}

message SubjectAlternativeName {
        SubjectAlternativeNameType type = 1;
        oneof identity {
                // A regular expression describing the expected value for
                // the SAN.
                string regexp = 2;
                // The exact value to match against.
                string value = 3;
        }
}

// A chain of X.509 certificates.
message X509CertificateChain {
        // The chain of certificates, with indices 0 to n.
        // The first certificate in the array must be the leaf
        // certificate used for signing.
        //
        // Signers MUST NOT include their root CA certificates in their embedded
        // certificate chains, and SHOULD NOT include intermediate CA
        // certificates that appear in independent roots of trust.
        //
        // Verifiers MUST validate the chain carefully to ensure that it chains
        // up to a root CA certificate that they trust, regardless of whether
        // the chain includes additional intermediate/root CA certificates.
        // Verifiers MAY enforce additional constraints, such as requiring that
        // all intermediate CA certificates appear in an independent root of
        // trust.
        //
        // Verifiers SHOULD handle old or non-complying bundles that have
        // additional intermediate/root CA certificates.
        repeated X509Certificate certificates = 1;
}

// The time range is closed and includes both the start and end times,
// (i.e., [start, end]).
// End is optional to be able to capture a period that has started but
// has no known end.
message TimeRange {
        google.protobuf.Timestamp start = 1;
        optional google.protobuf.Timestamp end = 2;
}
