Example #1
0
        /// <inheritsdoc />
        public override bool TryUnwrapKey(ReadOnlySpan <byte> keyBytes, Span <byte> destination, JwtHeaderDocument header, out int bytesWritten)
        {
            if (!header.TryGetHeaderParameter(JwtHeaderParameterNames.Epk.EncodedUtf8Bytes, out var epk))
            {
                ThrowHelper.ThrowJwtDescriptorException_HeaderIsRequired(JwtHeaderParameterNames.Epk);
            }

            header.TryGetHeaderParameter(JwtHeaderParameterNames.Apu.EncodedUtf8Bytes, out JwtElement apu);
            header.TryGetHeaderParameter(JwtHeaderParameterNames.Apv.EncodedUtf8Bytes, out JwtElement apv);
            byte[] secretAppend = BuildSecretAppend(apu, apv);

            ReadOnlySpan <byte> exchangeHash;

            using (var ephemeralKey = ECDiffieHellman.Create(ECJwk.FromJwtElement(epk).ExportParameters()))
            {
                var privateKey = _key.CreateEcdhKey();
                if (ephemeralKey.KeySize != privateKey.KeySize)
                {
                    return(ThrowHelper.TryWriteError(out bytesWritten));
                }

                exchangeHash = new ReadOnlySpan <byte>(privateKey.DeriveKeyFromHash(ephemeralKey.PublicKey, _hashAlgorithm, _secretPreprend, secretAppend), 0, _keySizeInBytes);
            }

            if (Algorithm.ProduceEncryptionKey)
            {
                using var keyUnwrapper = new AesKeyUnwrapper(exchangeHash, EncryptionAlgorithm, _keyManagementAlgorithm !);
                return(keyUnwrapper.TryUnwrapKey(keyBytes, destination, header, out bytesWritten));
            }
            else
            {
                exchangeHash.CopyTo(destination);
                bytesWritten = destination.Length;
                return(true);
            }
        }