Attestation (dsee envelope) -> { message: { Statement(in-toto): [subject, predicate] }, signature: "sig" }. NOTE: It currently only supports cosign key based signing.
(ctx context.Context)
| 113 | // Attestation (dsee envelope) -> { message: { Statement(in-toto): [subject, predicate] }, signature: "sig" }. |
| 114 | // NOTE: It currently only supports cosign key based signing. |
| 115 | func (ab *AttestationRenderer) Render(ctx context.Context) (*dsse.Envelope, *protobundle.Bundle, error) { |
| 116 | ab.logger.Debug().Msg("generating in-toto statement") |
| 117 | |
| 118 | statement, err := ab.renderer.Statement(ctx) |
| 119 | if err != nil { |
| 120 | return nil, nil, err |
| 121 | } |
| 122 | |
| 123 | if err := statement.Validate(); err != nil { |
| 124 | return nil, nil, fmt.Errorf("validating intoto statement: %w", err) |
| 125 | } |
| 126 | |
| 127 | rawStatement, err := protojson.Marshal(statement) |
| 128 | if err != nil { |
| 129 | return nil, nil, err |
| 130 | } |
| 131 | |
| 132 | signedAtt, err := ab.dsseSigner.SignMessage(bytes.NewReader(rawStatement)) |
| 133 | if err != nil { |
| 134 | return nil, nil, fmt.Errorf("signing message: %w", err) |
| 135 | } |
| 136 | |
| 137 | ab.logger.Debug().Msg("signing the statement") |
| 138 | var dsseEnvelope dsse.Envelope |
| 139 | if err := json.Unmarshal(signedAtt, &dsseEnvelope); err != nil { |
| 140 | return nil, nil, err |
| 141 | } |
| 142 | decodedSig, err := base64.StdEncoding.DecodeString(dsseEnvelope.Signatures[0].Sig) |
| 143 | if err != nil { |
| 144 | return nil, nil, fmt.Errorf("decoding signature: %w", err) |
| 145 | } |
| 146 | |
| 147 | // If timestamp service is configured, let's sign with it |
| 148 | var tsaSig []byte |
| 149 | if ab.att.GetSigningOptions().GetTimestampAuthorityUrl() != "" { |
| 150 | ab.logger.Debug().Msg("adding a timestamp") |
| 151 | tsa := signer.NewTimestampSigner(ab.att.GetSigningOptions().GetTimestampAuthorityUrl()) |
| 152 | tsaSig, err = tsa.SignMessage(ctx, decodedSig) |
| 153 | if err != nil { |
| 154 | return nil, nil, fmt.Errorf("adding timestamp: %w", err) |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | // Create sigstore bundle for the contents of this attestation |
| 159 | bundle, err := ab.envelopeToBundle(&dsseEnvelope, tsaSig) |
| 160 | if err != nil { |
| 161 | return nil, nil, fmt.Errorf("loading bundle: %w", err) |
| 162 | } |
| 163 | |
| 164 | return &dsseEnvelope, bundle, nil |
| 165 | } |
| 166 | |
| 167 | func (ab *AttestationRenderer) envelopeToBundle(dsseEnvelope *dsse.Envelope, tsaSig []byte) (*protobundle.Bundle, error) { |
| 168 | bundle, err := attestation.BundleFromDSSEEnvelope(dsseEnvelope) |