Ejemplo n.º 1
0
        public Signer(OneKey key, CBORObject algorithm = null)
        {
            if (algorithm != null)
            {
                AddAttribute(HeaderKeys.Algorithm, algorithm, UNPROTECTED);
            }
            if (key.ContainsName(CoseKeyKeys.KeyIdentifier))
            {
                AddAttribute(HeaderKeys.KeyId, key[CoseKeyKeys.KeyIdentifier], UNPROTECTED);
            }

            if (key.ContainsName("use"))
            {
                string usage = key.AsString("use");
                if (usage != "sig")
                {
                    throw new Exception("Key cannot be used for encryption");
                }
            }

            if (key.ContainsName(CoseKeyKeys.Key_Operations))
            {
                CBORObject usageObject = key[CoseKeyKeys.Key_Operations];
                bool       validUsage  = false;

                if (usageObject.Type != CBORType.Array)
                {
                    throw new Exception("key_ops is incorrectly formed");
                }
                for (int i = 0; i < usageObject.Count; i++)
                {
                    switch (usageObject[i].AsString())
                    {
                    case "encrypt":
                    case "keywrap":
                        validUsage = true;
                        break;
                    }
                }

                if (!validUsage)
                {
                    throw new Exception("Key cannot be used for encryption");
                }
            }

            _keyToSign = key;
        }
Ejemplo n.º 2
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));
        }
Ejemplo n.º 3
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");
            }
        }