func()

in client/client.go [605:680]


func (c *StetClient) Decrypt(ctx context.Context, input io.Reader, output io.Writer, stetConfig *configpb.StetConfig) (*StetMetadata, error) {
	config := stetConfig.GetDecryptConfig()
	if config == nil {
		return nil, fmt.Errorf("nil DecryptConfig passed to Decrypt()")
	}

	metadata, err := ReadMetadata(input)
	if err != nil {
		return nil, fmt.Errorf("error reading metadata: %v", err)
	}

	// Find matching KeyConfig.
	var matchingKeyConfig *configpb.KeyConfig

	for _, keyCfg := range config.GetKeyConfigs() {
		if proto.Equal(keyCfg, metadata.GetKeyConfig()) {
			matchingKeyConfig = keyCfg
			break
		}
	}

	if matchingKeyConfig == nil {
		return nil, fmt.Errorf("no known KeyConfig matches given data")
	}

	// Unwrap shares and validate.
	opts := sharesOpts{
		kekInfos:        matchingKeyConfig.GetKekInfos(),
		asymmetricKeys:  stetConfig.GetAsymmetricKeys(),
		confSpaceConfig: c.newConfSpaceConfig(stetConfig),
	}

	unwrappedShares, err := c.unwrapAndValidateShares(ctx, metadata.GetShares(), opts)
	if err != nil {
		return nil, fmt.Errorf("error unwrapping and validating shares: %v", err)
	}

	// Verify we have enough unwrapped shares for the key config.
	if err := enoughUnwrappedShares(unwrappedShares, matchingKeyConfig); err != nil {
		return nil, fmt.Errorf("not enough unwrapped shares to recombine DEK, see logs for unwrap details: %v", err)
	} else if len(unwrappedShares) < len(matchingKeyConfig.GetKekInfos()) {
		glog.Warningf("Recieved enough unwrapped shares to recombine DEK, but not all shares unwrapped successfully: %v of %v unwrapped, see logs for unwrap details.", len(unwrappedShares), len(matchingKeyConfig.GetKekInfos()))
	}

	combinedShares, err := shares.CombineUnwrappedShares(matchingKeyConfig, unwrappedShares)
	if err != nil {
		return nil, fmt.Errorf("error combining unwrapped shares: %v", err)
	}

	var combinedDEK shares.DEK
	copy(combinedDEK[:], combinedShares)

	// Generate AAD and decrypt ciphertext.
	aad, err := MetadataToAAD(metadata)
	if err != nil {
		return nil, fmt.Errorf("error serializing metadata: %v", err)
	}

	// Now `input` is at the start of ciphertext to pass to Tink.
	if err := AeadDecrypt(combinedDEK, input, output, aad); err != nil {
		return nil, fmt.Errorf("error decrypting data: %v", err)
	}

	// Return URIs of keys used during decryption.
	var keyURIs []string
	for _, unwrapped := range unwrappedShares {
		if unwrapped.URI != "" {
			keyURIs = append(keyURIs, unwrapped.URI)
		}
	}

	return &StetMetadata{
		KeyUris: keyURIs,
		BlobID:  metadata.GetBlobId(),
	}, nil
}