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); }
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); }
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)); }
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(); }
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(); }
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"); } }