func()

in client/client.go [382:502]


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

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

	// In order to support k-of-n decryption, don't exit early if share
	// share unwrapping fails. Attempt to unwrap all shares and just
	// return the subset of ones that succeeded, and let the Shamir's
	// implementation handle the subset of shares.
	var unwrappedShares []shares.UnwrappedShare
	for i, wrapped := range wrappedShares {
		unwrapped := shares.UnwrappedShare{}
		kek := opts.kekInfos[i]
		glog.Infof("Attempting to unwrap share #%v, URI %v", i+1, kek.GetKekUri())

		switch x := kek.KekType.(type) {
		case *configpb.KekInfo_RsaFingerprint:
			key, err := PrivateKeyForRSAFingerprint(kek, opts.asymmetricKeys)
			if err != nil {
				glog.Errorf("Failed to find private key for RSA fingerprint: %v", err)
				continue
			}

			unwrapped.Share, err = rsa.DecryptOAEP(sha256.New(), rand.Reader, key, wrapped.GetShare(), nil)
			if err != nil {
				glog.Errorf("Error unwrapping key share for %v: %v", kek.GetKekUri(), err)
				continue
			}

		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_DECRYPT_ONLY_MODE)
			}

			kmsClient, err := kmsClients.Client(ctx, creds)
			if err != nil {
				glog.Errorf("Error initializing Cloud KMS Client with credentials \"%v\" for %v: %v", creds, kek.GetKekUri(), err)
				continue
			}

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

			var uri string
			// Unwrap share via KMS.
			switch pl := cryptoKey.GetPrimary().ProtectionLevel; pl {
			case rpb.ProtectionLevel_SOFTWARE, rpb.ProtectionLevel_HSM:
				unwrapOpts := cloudkms.UnwrapOpts{
					Share:   wrapped.GetShare(),
					KeyName: strings.TrimPrefix(kek.GetKekUri(), gcpKeyPrefix),
				}
				unwrapped.Share, err = cloudkms.UnwrapShare(ctx, kmsClient, unwrapOpts)
				if err != nil {
					glog.Errorf("Error unwrapping key sharefor %v: %v", kek.GetKekUri(), err)
					continue
				}

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

				unwrapped.Share, err = c.ekmSecureSessionUnwrap(ctx, wrapped.GetShare(), *kmd, nil)
				if err != nil {
					glog.Warningf("Error unwrapping with external EKM for %v: %v", kmd.uri, err)
					continue
				}
				uri = kmd.uri
			case rpb.ProtectionLevel_EXTERNAL_VPC:
				kmd, ekmCerts, err := c.getExternalVPCKeyInfo(ctx, cryptoKey, creds)
				if err != nil {
					return nil, fmt.Errorf("error getting external VPC key info: %v", err)
				}

				unwrapped.Share, err = c.ekmSecureSessionUnwrap(ctx, wrapped.GetShare(), *kmd, ekmCerts)
				if err != nil {
					glog.Errorf("Error unwrapping with external EKM for %v: %v", kmd.uri, err)
					continue
				}

				uri = kmd.uri
			default:
				glog.Errorf("Unsupported protection level for %v: %v", kek.GetKekUri(), pl)
				continue
			}

			// 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.
			unwrapped.URI = uri

		default:
			glog.Errorf("Unsupported KekInfo type for %v: %v", kek.GetKekUri(), x)
			continue
		}

		if !shares.ValidateShare(unwrapped.Share, wrapped.GetHash()) {
			glog.Errorf("Unwrapped share %v does not have the expected hash", i)
			continue
		}

		glog.Infof("Successfully unwrapped share %v", unwrapped.URI)
		unwrappedShares = append(unwrappedShares, unwrapped)
	}

	return unwrappedShares, nil
}