Beispiel #1
0
        private byte[] Sign(byte[] bytesToBeSigned)
        {
            if (signature != null)
            {
                return(signature);
            }


            string alg = null; // Get the set algorithm or infer one

            try {
                alg = FindAttribute("alg").AsString();
            }
            catch (Exception) {
                // ignored
            }

            if (alg == null)
            {
                switch (keyToSign.AsString("kty"))
                {
                case "RSA":
                    alg = "PS256";
                    break;

                case "EC":
                    switch (keyToSign.AsString("crv"))
                    {
                    case "P-256":
                        alg = "ES256";
                        break;

                    case "P-384":
                        alg = "ES384";
                        break;

                    case "P-521":
                        alg = "ES512";
                        break;

                    default:
                        throw new JoseException("Unknown curve");
                    }

                    break;

                default:
                    throw new JoseException("Unknown or unsupported key type " + keyToSign.AsString("kty"));
                }

                UnprotectedMap.Add("alg", alg);
            }

            signature = keyToSign.ComputeMac(bytesToBeSigned, alg);
            return(signature);
        }
Beispiel #2
0
        private void AES_GCM_KeyWrap(int keySize, EncryptMessage msg)
        {
            if (_mKey.AsString("kty") != "oct")
            {
                throw new JoseException("Incorrect key type");
            }
            byte[] keyBytes = _mKey.AsBytes("k");
            if (keyBytes.Length != keySize / 8)
            {
                throw new JoseException("Key is not the correct size");
            }

            GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine(), new BasicGcmMultiplier());
            KeyParameter   contentKey;

            //  The requirements from JWA
            //  IV is 96 bits
            //  Authentication tag is 128 bits
            //  key sizes are 128, 192 and 256 bits
            //  Keywrap says that there is no AAD

            contentKey = new KeyParameter(keyBytes);
            byte[] a  = new byte[0];
            byte[] iv = new byte[96 / 8];


            Message.s_PRNG.NextBytes(iv);
            if (msg.FindAttribute(CBORObject.FromObject("iv"), PROTECTED) != null)
            {
                msg.AddAttribute("iv", Message.base64urlencode(iv), PROTECTED);
            }
            else if (msg.FindAttribute(CBORObject.FromObject("iv"), UNPROTECTED) != null)
            {
                msg.AddAttribute("iv", Message.base64urlencode(iv), UNPROTECTED);
            }
            else
            {
                UnprotectedMap.Add("iv", Message.base64urlencode(iv));
            }

            AeadParameters parameters = new AeadParameters(contentKey, 128, iv, a);

            cipher.Init(true, parameters);
            byte[] c   = new byte[cipher.GetOutputSize(_payload.Length)];
            int    len = cipher.ProcessBytes(_payload, 0, _payload.Length, c, 0);

            len += cipher.DoFinal(c, len);

            if (len != c.Length)
            {
                throw new JoseException("NYI");
            }
            byte[] tag = new byte[128 / 8];
            Array.Copy(c, c.Length - tag.Length, tag, 0, tag.Length);

            if (msg.FindAttribute(CBORObject.FromObject("tag"), PROTECTED) != null)
            {
                msg.AddAttribute("tag", Message.base64urlencode(tag), PROTECTED);
            }
            else if (msg.FindAttribute(CBORObject.FromObject("tag"), UNPROTECTED) != null)
            {
                msg.AddAttribute("tag", Message.base64urlencode(tag), UNPROTECTED);
            }
            else
            {
                UnprotectedMap.Add("tag", Message.base64urlencode(tag));
            }

            _rgbEncrypted = c;
            Array.Resize(ref _rgbEncrypted, c.Length - tag.Length);
        }
Beispiel #3
0
        private byte[] Sign(byte[] bytesToBeSigned)
        {
            CBORObject alg; // Get the set algorithm or infer one

            alg = FindAttribute(HeaderKeys.Algorithm);

            if (alg == null)
            {
                if (_keyToSign[CoseKeyKeys.KeyType].Type == CBORType.Integer)
                {
                    switch ((GeneralValuesInt)_keyToSign[CoseKeyKeys.KeyType].AsInt32())
                    {
                    case GeneralValuesInt.KeyType_RSA:
                        alg = AlgorithmValues.RSA_PSS_256;
                        break;

                    case GeneralValuesInt.KeyType_EC2:
                        if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Integer)
                        {
                            switch ((GeneralValuesInt)_keyToSign[CoseKeyParameterKeys.EC_Curve].AsInt32())
                            {
                            case GeneralValuesInt.P256:
                                alg = AlgorithmValues.ECDSA_256;
                                break;

                            case GeneralValuesInt.P384:
                                alg = AlgorithmValues.ECDSA_384;
                                break;

                            case GeneralValuesInt.P521:
                                alg = AlgorithmValues.ECDSA_512;
                                break;

                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.TextString)
                        {
                            switch (_keyToSign[CoseKeyParameterKeys.EC_Curve].AsString())
                            {
                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else
                        {
                            throw new CoseException("Curve is incorrectly encoded");
                        }

                        break;

                    case GeneralValuesInt.KeyType_OKP:
                        if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Integer)
                        {
                            switch ((GeneralValuesInt)_keyToSign[CoseKeyParameterKeys.EC_Curve].AsInt32())
                            {
                            case GeneralValuesInt.Ed25519:
                                alg = AlgorithmValues.EdDSA;
                                break;

                            case GeneralValuesInt.Ed448:
                                alg = AlgorithmValues.EdDSA;
                                break;

                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.TextString)
                        {
                            switch (_keyToSign[CoseKeyParameterKeys.EC_Curve].AsString())
                            {
                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else
                        {
                            throw new CoseException("Curve is incorrectly encoded");
                        }

                        break;

                    default:
                        throw new Exception("Unknown or unsupported key type " + _keyToSign.AsString("kty"));
                    }
                }
                else if (_keyToSign[CoseKeyKeys.KeyType].Type == CBORType.TextString)
                {
                    throw new CoseException("Unknown or unsupported key type " + _keyToSign[CoseKeyKeys.KeyType].AsString());
                }
                else
                {
                    throw new CoseException("Key type is not correctly encoded");
                }

                UnprotectedMap.Add(HeaderKeys.Algorithm, alg);
            }

            return(Sign(bytesToBeSigned, alg, _keyToSign));
        }
Beispiel #4
0
        public virtual void MAC()
        {
            CBORObject alg;
            int        cbitKey;

            if (rgbContent == null)
            {
                throw new CoseException("No Content Specified");
            }

            //  Get the algorithm we are using - the default is AES GCM

            alg = FindAttribute(HeaderKeys.Algorithm);
            if (alg == null)
            {
                alg = AlgorithmValues.HMAC_SHA_256;
                if (UnprotectedMap == null)
                {
                    UnprotectedMap = CBORObject.NewMap();
                }
                UnprotectedMap.Add(HeaderKeys.Algorithm, alg);
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                    cbitKey = 128;
                    break;

                case "AES-CMAC-256/64":
                    cbitKey = 256;
                    break;

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                case AlgorithmValuesInt.HMAC_SHA_256:
                    cbitKey = 256;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_384:
                    cbitKey = 384;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_512:
                    cbitKey = 512;
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                    cbitKey = 128;
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    cbitKey = 256;
                    break;

                default:
                    throw new CoseException("MAC algorithm not recognized " + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            byte[] contentKey = null;

            //  Determine if we are doing a direct encryption
            int recipientTypes = 0;

            foreach (Recipient key in _recipientList)
            {
                switch (key.recipientType)
                {
                case RecipientType.direct:
                case RecipientType.keyAgreeDirect:
                    if ((recipientTypes & 1) != 0)
                    {
                        throw new CoseException("It is not legal to have two direct recipients in a message");
                    }
                    recipientTypes |= 1;
                    contentKey      = key.GetKey(alg);
                    break;

                default:
                    recipientTypes |= 2;
                    break;
                }
            }

            if (recipientTypes == 3)
            {
                throw new CoseException("It is not legal to mix direct and indirect recipients in a message");
            }
            if (recipientTypes == 0)
            {
                throw new CoseException("No recipients supplied");
            }

            if (contentKey == null)
            {
                contentKey = new byte[cbitKey / 8];
                s_PRNG.NextBytes(contentKey);
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                case "AES-CMAC-256/64":
                    RgbTag = AES_CMAC(alg, contentKey);
                    break;

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256:
                case AlgorithmValuesInt.HMAC_SHA_384:
                case AlgorithmValuesInt.HMAC_SHA_512:
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                    RgbTag = HMAC(alg, contentKey);
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    RgbTag = AES_CBC_MAC(alg, contentKey);
                    break;

                default:
                    throw new CoseException("MAC algorithm not recognized " + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }


            foreach (Recipient key in _recipientList)
            {
                key.SetContent(contentKey);
                key.Encrypt();
            }

#if FOR_EXAMPLES
            m_cek = contentKey;
#endif
            ProcessCounterSignatures();
        }
Beispiel #5
0
        public void Compute(byte[] contentKey)
        {
            CBORObject alg;

            alg = FindAttribute(HeaderKeys.Algorithm);
            if (alg == null)
            {
                alg = AlgorithmValues.HMAC_SHA_256;
                if (UnprotectedMap == null)
                {
                    UnprotectedMap = CBORObject.NewMap();
                }
                UnprotectedMap.Add(HeaderKeys.Algorithm, alg);
            }

            if (rgbContent == null)
            {
                throw new CoseException("No Content Specified");
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                case "AES-CMAC-256/64":
                    RgbTag = AES_CMAC(alg, contentKey);
                    break;

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256:
                case AlgorithmValuesInt.HMAC_SHA_384:
                case AlgorithmValuesInt.HMAC_SHA_512:
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                    RgbTag = HMAC(alg, contentKey);
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    RgbTag = AES_CBC_MAC(alg, contentKey);
                    break;

                default:
                    throw new CoseException("MAC algorithm not recognized " + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            ProcessCounterSignatures();
        }
Beispiel #6
0
        private byte[] _Sign(byte[] bytesToBeSigned)
        {
            CBORObject alg;  // Get the set algorithm or infer one

            if (rgbContent == null)
            {
                throw new CoseException("No Content Specified");
            }

            alg = FindAttribute(HeaderKeys.Algorithm);

            if (alg == null)
            {
                if (_keyToSign[CoseKeyKeys.KeyType].Type == CBORType.Integer)
                {
                    switch ((GeneralValuesInt)_keyToSign[CoseKeyKeys.KeyType].AsInt32())
                    {
                    case GeneralValuesInt.KeyType_RSA:
                        alg = AlgorithmValues.RSA_PSS_256;
                        break;

                    case GeneralValuesInt.KeyType_EC2:
                        if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Integer)
                        {
                            switch ((GeneralValuesInt)_keyToSign[CoseKeyParameterKeys.EC_Curve].AsInt32())
                            {
                            case GeneralValuesInt.P256:
                                alg = AlgorithmValues.ECDSA_256;
                                break;

                            case GeneralValuesInt.P521:
                                alg = AlgorithmValues.ECDSA_512;
                                break;

                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.TextString)
                        {
                            switch (_keyToSign[CoseKeyParameterKeys.EC_Curve].AsString())
                            {
                            case "P-384":
                                alg = CBORObject.FromObject("ES384");
                                break;

                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else
                        {
                            throw new CoseException("Curve is incorrectly encoded");
                        }
                        break;

                    case GeneralValuesInt.KeyType_OKP:
                        if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Integer)
                        {
                            switch ((GeneralValuesInt)_keyToSign[CoseKeyParameterKeys.EC_Curve].AsInt32())
                            {
                            case GeneralValuesInt.Ed25519:
                                alg = AlgorithmValues.EdDSA;
                                break;

                            case GeneralValuesInt.Ed448:
                                alg = AlgorithmValues.EdDSA;
                                break;

                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.TextString)
                        {
                            switch (_keyToSign[CoseKeyParameterKeys.EC_Curve].AsString())
                            {
                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else
                        {
                            throw new CoseException("Curve is incorrectly encoded");
                        }

                        break;

                    default:
                        throw new CoseException("Unknown or unsupported key type " + _keyToSign.AsString("kty"));
                    }
                }
                else if (_keyToSign[CoseKeyKeys.KeyType].Type == CBORType.TextString)
                {
                    throw new CoseException("Unknown or unsupported key type " + _keyToSign[CoseKeyKeys.KeyType].AsString());
                }
                else
                {
                    throw new CoseException("Key type is not correctly encoded");
                }
                UnprotectedMap.Add(HeaderKeys.Algorithm, alg);
            }

            IDigest digest  = null;
            IDigest digest2 = null;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "ES384":
                case "PS384":
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                case "HSS-LMS":
                    break;

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.RSA_PSS_256:
                    digest  = new Sha256Digest();
                    digest2 = new Sha256Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.RSA_PSS_384:
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_512:
                case AlgorithmValuesInt.RSA_PSS_512:
                    digest  = new Sha512Digest();
                    digest2 = new Sha512Digest();
                    break;

                case AlgorithmValuesInt.EdDSA:
                    break;

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "HSS-LMS":
                    HashSig sig       = new HashSig(_keyToSign[CoseKeyParameterKeys.Lms_Private].AsString());
                    byte[]  signBytes = sig.Sign(bytesToBeSigned);

                    _keyToSign.Replace(CoseKeyParameterKeys.Lms_Private, CBORObject.FromObject(sig.PrivateKey));
                    return(signBytes);

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.RSA_PSS_256:
                case AlgorithmValuesInt.RSA_PSS_384:
                case AlgorithmValuesInt.RSA_PSS_512: {
                    PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetByteLength());

                    RsaKeyParameters prv = new RsaPrivateCrtKeyParameters(
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_n),
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_e),
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_d),
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_p),
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_q),
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dP),
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dQ),
                        _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_qInv));
                    ParametersWithRandom param = new ParametersWithRandom(prv, GetPRNG());

                    signer.Init(true, param);
                    signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    return(signer.GenerateSignature());
                }

                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.ECDSA_512: {
                    CBORObject privateKeyD = _keyToSign[CoseKeyParameterKeys.EC_D];
                    if (privateKeyD == null)
                    {
                        throw new CoseException("Private key required to sign");
                    }

                    SecureRandom random = GetPRNG();

                    digest.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    byte[] digestedMessage = new byte[digest.GetDigestSize()];
                    digest.DoFinal(digestedMessage, 0);

                    X9ECParameters         p          = _keyToSign.GetCurve();
                    ECDomainParameters     parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);
                    ECPrivateKeyParameters privKey    =
                        new ECPrivateKeyParameters("ECDSA", ConvertBigNum(privateKeyD), parameters);
                    ParametersWithRandom param = new ParametersWithRandom(privKey, random);

                    ECDsaSigner ecdsa = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
                    ecdsa.Init(true, param);

                    BigInteger[] sig = ecdsa.GenerateSignature(digestedMessage);

                    byte[] r = sig[0].ToByteArrayUnsigned();
                    byte[] s = sig[1].ToByteArrayUnsigned();

                    int cbR = (p.Curve.FieldSize + 7) / 8;

                    byte[] sigs = new byte[cbR * 2];
                    Array.Copy(r, 0, sigs, cbR - r.Length, r.Length);
                    Array.Copy(s, 0, sigs, cbR + cbR - s.Length, s.Length);

                    return(sigs);
                }

#if true
                case AlgorithmValuesInt.EdDSA: {
                    ISigner eddsa;
                    if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed25519))
                    {
                        Ed25519PrivateKeyParameters privKey =
                            new Ed25519PrivateKeyParameters(_keyToSign[CoseKeyParameterKeys.OKP_D].GetByteString(), 0);
                        eddsa = new Ed25519Signer();
                        eddsa.Init(true, privKey);
                    }
                    else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed448))
                    {
                        Ed448PrivateKeyParameters privKey =
                            new Ed448PrivateKeyParameters(_keyToSign[CoseKeyParameterKeys.OKP_D].GetByteString(), 0);
                        eddsa = new Ed448Signer(new byte[0]);
                        eddsa.Init(true, privKey);
                    }
                    else
                    {
                        throw new CoseException("Unrecognized curve");
                    }


                    eddsa.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);

                    return(eddsa.GenerateSignature());
                }
#endif

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }
        }