func()

in client/client.go [272:379]


func (c *StetClient) wrapShares(ctx context.Context, unwrappedShares [][]byte, opts sharesOpts) (wrappedShares []*configpb.WrappedShare, keyURIs []string, err error) {
	if len(unwrappedShares) != len(opts.kekInfos) {
		return nil, nil, fmt.Errorf("number of shares to wrap (%d) does not match number of KEKs (%d)", len(unwrappedShares), len(opts.kekInfos))
	}

	var kmsClients *cloudkms.ClientFactory
	if c.testKMSClients != nil {
		kmsClients = c.testKMSClients
	} else {
		kmsClients = cloudkms.NewClientFactory(c.Version)
	}
	defer kmsClients.Close()

	for i, share := range unwrappedShares {
		wrapped := &configpb.WrappedShare{
			Hash: shares.HashShare(share),
		}

		kek := opts.kekInfos[i]

		switch x := kek.KekType.(type) {
		case *configpb.KekInfo_RsaFingerprint:
			key, err := PublicKeyForRSAFingerprint(kek, opts.asymmetricKeys)
			if err != nil {
				return nil, nil, fmt.Errorf("failed to find public key for RSA fingerprint: %w", err)
			}

			wrapped.Share, err = rsa.EncryptOAEP(sha256.New(), rand.Reader, key, share, nil)
			if err != nil {
				return nil, nil, fmt.Errorf("error wrapping key share: %v", err)
			}

		case *configpb.KekInfo_KekUri:
			// Configure CloudKMS Client, with Confidential Space credentials if applicable.
			creds := ""
			if opts.confSpaceConfig != nil {
				creds = opts.confSpaceConfig.FindMatchingCredentials(kek.GetKekUri(), configpb.CredentialMode_ENCRYPT_ONLY_MODE)
			}

			kmsClient, err := kmsClients.Client(ctx, creds)
			if err != nil {
				return nil, nil, fmt.Errorf("error initializing Cloud KMS Client with credentials \"%v\": %v", creds, err)
			}

			cryptoKey, err := getKekCryptoKey(ctx, kmsClient, kek)
			if err != nil {
				return nil, nil, fmt.Errorf("Error retrieving KEK Metadata: %v", err)
			}

			var uri string
			// Wrap share via KMS.
			switch pl := cryptoKey.GetPrimary().ProtectionLevel; pl {
			case rpb.ProtectionLevel_SOFTWARE, rpb.ProtectionLevel_HSM:
				var err error
				wrapOpts := cloudkms.WrapOpts{
					Share:   share,
					KeyName: strings.TrimPrefix(kek.GetKekUri(), gcpKeyPrefix),
				}
				wrapped.Share, err = cloudkms.WrapShare(ctx, kmsClient, wrapOpts)
				if err != nil {
					return nil, nil, fmt.Errorf("error wrapping key share: %v", err)
				}

				uri = kek.GetKekUri()
			case rpb.ProtectionLevel_EXTERNAL:
				kmd, err := externalKEKMetadata(cryptoKey)
				if err != nil {
					return nil, nil, fmt.Errorf("error creating KEK Metadata: %v", err)
				}

				// A nil ekmCertPool indicates the host's Root CAs will be used to connect to the EKM.
				ekmWrappedShare, err := c.ekmSecureSessionWrap(ctx, share, *kmd, nil)
				if err != nil {
					return nil, nil, fmt.Errorf("error wrapping with secure session: %v", err)
				}

				wrapped.Share = ekmWrappedShare
				uri = kmd.uri
			case rpb.ProtectionLevel_EXTERNAL_VPC:
				kmd, ekmCerts, err := c.getExternalVPCKeyInfo(ctx, cryptoKey, creds)
				if err != nil {
					return nil, nil, fmt.Errorf("error getting external VPC key info: %v", err)
				}

				ekmWrappedShare, err := c.ekmSecureSessionWrap(ctx, share, *kmd, ekmCerts)
				if err != nil {
					return nil, nil, fmt.Errorf("error wrapping with secure session: %v", err)
				}

				wrapped.Share = ekmWrappedShare
				uri = kmd.uri
			default:
				return nil, nil, fmt.Errorf("unsupported protection level %v", pl)
			}

			// Return the URI used: the Cloud KMS one in the case of a software
			// or HSM key, and the external key URI for an external key.
			keyURIs = append(keyURIs, uri)

		default:
			return nil, nil, fmt.Errorf("unsupported KekInfo type: %v", x)
		}

		wrappedShares = append(wrappedShares, wrapped)
	}

	return wrappedShares, keyURIs, nil
}