public CoralFormField(CBORObject type, CBORObject value, Cori baseCori, CoralDictionary dictionary) { CBORObject o = (CBORObject)dictionary.Reverse(type, false); if (o == null) { FieldTypeInt = type.AsInt32(); } else if (o.Type == CBORType.Array) { FieldType = new Cori(o); if (type.Type == CBORType.Integer) { FieldTypeInt = type.AsInt32(); } } else { throw new ArgumentException("Not a valid form field type"); } o = (CBORObject)dictionary.Reverse(value, true); if (o == null) { LiteralInt = value.AsInt32(); } else if (o.Type == CBORType.Array) { Url = new Cori(o); if (baseCori != null) { Url = Url.ResolveTo(baseCori); } if (value.Type == CBORType.Integer) { LiteralInt = value.Untag().AsInt32(); } } else { Literal = o; if (value.IsTagged && value.HasOneTag(CoralDictionary.DictionaryTag) && value.Type == CBORType.Integer) { LiteralInt = value.Untag().AsInt32(); } } }
public static String GetAlgorithmName(CBORObject cborValue) { switch (cborValue.AsInt32()) { case -7: return("SHA256withECDSA"); case -35: return("SHA384withECDSA"); case -36: return("SHA512withECDSA"); case -37: return("SHA256withRSA/PSS"); case -38: return("SHA384withRSA/PSS"); case -39: return("SHA512withRSA/PSS"); default: break; } return(null); }
public int GetKeySize(CBORObject alg) { if (alg.Type == CBORType.TextString) { throw new CoseException("Unknown Algorithm Specified"); } else if (alg.Type == CBORType.Integer) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.AES_GCM_128: case AlgorithmValuesInt.AES_CCM_16_64_128: case AlgorithmValuesInt.AES_CCM_16_128_128: case AlgorithmValuesInt.AES_CCM_64_64_128: case AlgorithmValuesInt.AES_CCM_64_128_128: return(128); case AlgorithmValuesInt.AES_GCM_192: return(192); case AlgorithmValuesInt.AES_GCM_256: case AlgorithmValuesInt.AES_CCM_16_64_256: case AlgorithmValuesInt.AES_CCM_16_128_256: case AlgorithmValuesInt.AES_CCM_64_64_256: case AlgorithmValuesInt.AES_CCM_64_128_256: case AlgorithmValuesInt.ChaCha20_Poly1305: return(256); default: throw new CoseException("Unknown Algorithm Specified"); } } throw new CoseException("Invalid Algorithm Specified"); }
public void LookupString() { CBORObject result = _dictionary.Lookup("http://www.iana.org/assignments/relation/item>", false); Assert.AreEqual(CBORType.Integer, result.Type); Assert.AreEqual(1, result.AsInt32()); result = _dictionary.Lookup(CBORObject.FromObject("http://www.iana.org/assignments/relation/item>"), false); Assert.AreEqual(CBORType.Integer, result.Type); Assert.AreEqual(1, result.AsInt32()); result = _dictionary.Lookup(CBORObject.FromObject("http://www.iana.org/assignments/relation/item>"), true); Assert.AreEqual(CBORType.Integer, result.Type); Assert.IsTrue(result.IsTagged); Assert.IsTrue(result.HasOneTag(CoralDictionary.DictionaryTag)); Assert.AreEqual(1, result.Untag().AsInt32()); }
protected void DecryptWithKey(byte[] CEK) { if (RgbEncrypted == null) { throw new CoseException("No Encrypted Content Specified."); } if (CEK == null) { throw new CoseException("Null Key Supplied"); } CBORObject alg = FindAttribute(HeaderKeys.Algorithm); if (alg == null) { throw new CoseException("No Algorithm Specified"); } if (alg.Type == CBORType.TextString) { throw new CoseException("Algorithm not supported " + alg.AsString()); } else if (alg.Type == CBORType.Integer) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.AES_GCM_128: case AlgorithmValuesInt.AES_GCM_192: case AlgorithmValuesInt.AES_GCM_256: AES_Decrypt(alg, CEK); break; case AlgorithmValuesInt.AES_CCM_16_64_128: case AlgorithmValuesInt.AES_CCM_16_64_256: case AlgorithmValuesInt.AES_CCM_16_128_128: case AlgorithmValuesInt.AES_CCM_16_128_256: case AlgorithmValuesInt.AES_CCM_64_64_128: case AlgorithmValuesInt.AES_CCM_64_64_256: case AlgorithmValuesInt.AES_CCM_64_128_128: case AlgorithmValuesInt.AES_CCM_64_128_256: AES_CCM_Decrypt(alg, CEK); break; #if CHACHA20 case AlgorithmValuesInt.ChaCha20_Poly1305: ChaCha20_Poly1305_Decrypt(alg, CEK); break; #endif default: throw new CoseException("Unknown algorithm found"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } }
public void LookupInteger() { CBORObject result = _dictionary.Lookup(CBORObject.FromObject(5), true); Assert.AreEqual(CBORType.Integer, result.Type); Assert.IsFalse(result.IsTagged); Assert.AreEqual(5, result.AsInt32()); result = _dictionary.Lookup(CBORObject.FromObject(5), false); Assert.AreEqual(CBORType.Integer, result.Type); Assert.IsFalse(result.IsTagged); Assert.AreEqual(5, result.AsInt32()); result = _dictionary.Lookup(CBORObject.FromObject(-5), true); Assert.AreEqual(CBORType.Integer, result.Type); Assert.IsFalse(result.IsTagged); Assert.AreEqual(-5, result.AsInt32()); }
public void AddKey() { CBORObject result = _dictionary.Lookup("missing", false); Assert.AreEqual("missing", result.AsString()); _dictionary.Add(7, "missing"); result = _dictionary.Lookup("missing", false); Assert.AreEqual(7, result.AsInt32()); Cori cori = new Cori("coap://host2:99/path1/path2/path4"); _dictionary.Add(8, cori); Cori ciri2 = new Cori(cori.ToString()); result = _dictionary.Lookup(ciri2, false); Assert.AreEqual(8, result.AsInt32()); _dictionary.Add(9, new Cori(CBORObject.DecodeFromBytes(Hex.Decode("8405000664666F726D")))); Assert.ThrowsException <ArgumentException>(() => _dictionary.Add(10, CBORObject.FromObject(DateTime.UtcNow))); }
private static CBORObject readString(Stream stream, char firstChar) { var builder = new StringBuilder(); if (firstChar < (int)'0' && firstChar > (int)'9') { throw new CBORException("Invalid integer encoding"); } builder.Append(firstChar); while (true) { int c = stream.ReadByte(); if (c < 0) { throw new CBORException("Premature end of data"); } if (c >= (int)'0' && c <= (int)'9') { builder.Append((char)c); } else if (c == (int)':') { break; } else { throw new CBORException("Invalid integer encoding"); } } CBORObject number = CBORDataUtilities.ParseJSONNumber( builder.ToString(), true, true); var length = 0; try { length = number.AsInt32(); } catch (ArithmeticException ex) { throw new CBORException("Length too long", ex); } builder = new StringBuilder(); switch (DataUtilities.ReadUtf8(stream, length, builder, false)) { case -2: throw new CBORException("Premature end of data"); case -1: throw new CBORException("Invalid UTF-8"); } return(CBORObject.FromObject(builder.ToString())); }
public X9ECParameters GetCurve() { CBORObject cborKeyType = m_map[CoseKeyKeys.KeyType]; if (cborKeyType == null) { throw new CoseException("Malformed key struture"); } if ((cborKeyType.Type != CBORType.Number) && !((cborKeyType == GeneralValues.KeyType_EC) || (cborKeyType == GeneralValues.KeyType_OKP))) { throw new CoseException("Not an EC key"); } CBORObject cborCurve = m_map[CoseKeyParameterKeys.EC_Curve]; if (cborCurve.Type == CBORType.Number) { switch ((GeneralValuesInt)cborCurve.AsInt32()) { case GeneralValuesInt.P256: return(NistNamedCurves.GetByName("P-256")); case GeneralValuesInt.P384: return(NistNamedCurves.GetByName("P-384")); case GeneralValuesInt.P521: return(NistNamedCurves.GetByName("P-521")); case GeneralValuesInt.X25519: return(CustomNamedCurves.GetByName("CURVE25519")); default: throw new CoseException("Unsupported key type: " + cborKeyType.AsInt32()); } } else if (cborCurve.Type == CBORType.TextString) { switch (cborCurve.AsString()) { default: throw new CoseException("Unsupported key type: " + cborKeyType.AsString()); } } else { throw new CoseException("Incorrectly encoded key type"); } }
public void SetClaim(CBORObject claim, CBORObject value) { switch ((ClaimID)claim.AsInt32()) { case ClaimID.Issuer: case ClaimID.Subject: case ClaimID.Audience: if (value.Type != CBORType.TextString) { throw new CwtException("Claim value type is incorrect for the claim"); } break; case ClaimID.ExpirationTime: case ClaimID.NotBefore: case ClaimID.IssuedAt: if (value.Type != CBORType.Number) { throw new CwtException("Claim value type is incorrect for the claim"); } if ((value.GetTags().Count() != 1) || (value.OutermostTag.intValue() != 1)) { throw new CwtException("Claim value type is incorrect for the claim"); } break; case ClaimID.CWTId: if (value.Type != CBORType.ByteString) { throw new CwtException("Claim value type is incorrect for the claim"); } break; default: // We don't know how to check this break; } claims[claim] = value; }
public bool Validate(Recipient recipientReceiver) { byte[] rgbKey = null; int cbitKey; CBORObject alg = FindAttribute(COSE.HeaderKeys.Algorithm); 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 Exception("MAC algorithm is not recognized"); } } else if (alg.Type == CBORType.Number) { 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 Exception("MAC algorithm not recognized" + alg.AsInt32()); } } else { throw new CoseException("Algorithm incorrectly encoded"); } foreach (Recipient msgRecpient in recipientList) { if (recipientReceiver == msgRecpient) { try { rgbKey = msgRecpient.Decrypt(cbitKey, alg); } catch (CoseException) { } } else if (recipientReceiver == null) { ; } if (rgbKey != null) { break; } } if (rgbKey == null) { throw new CoseException("Recipient not found"); } byte[] rgbCheck; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "AES-CMAC-128/64": case "AES-CMAC-256/64": rgbCheck = AES_CMAC(alg, rgbKey); break; default: throw new Exception("MAC algorithm is not recognized"); } } else if (alg.Type == CBORType.Number) { 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: rgbCheck = HMAC(alg, rgbKey); 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: rgbCheck = AES_CBC_MAC(alg, rgbKey); break; default: throw new Exception("MAC algorithm not recognized" + alg.AsInt32()); } } else { throw new CoseException("Algorithm incorrectly encoded"); } bool fReturn = true; for (int i = 0; i < rgbCheck.Length; i++) { fReturn &= (rgbTag[i] == rgbCheck[i]); } return(fReturn); }
protected byte[] AES_CBC_MAC(CBORObject alg, byte[] K) { int cbitKey; int cbitTag; // Defaults to PKCS#7 IBlockCipher aes = new AesFastEngine(); KeyParameter ContentKey; // The requirements from spec // IV is 128 bits of zeros // key sizes are 128, 192 and 256 bits // Authentication tag sizes are 64 and 128 bits byte[] IV = new byte[128 / 8]; Debug.Assert(alg.Type == CBORType.Number); switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.AES_CBC_MAC_128_64: cbitKey = 128; cbitTag = 64; break; case AlgorithmValuesInt.AES_CBC_MAC_256_64: cbitKey = 256; cbitTag = 64; break; case AlgorithmValuesInt.AES_CBC_MAC_128_128: cbitKey = 128; cbitTag = 128; break; case AlgorithmValuesInt.AES_CBC_MAC_256_128: cbitKey = 256; cbitTag = 128; break; default: throw new Exception("Unrecognized algorithm"); } IMac mac = new CbcBlockCipherMac(aes, cbitTag, null); if (K.Length != cbitKey / 8) { throw new CoseException("Key is incorrectly sized"); } ContentKey = new KeyParameter(K); // Build the text to be digested mac.Init(ContentKey); byte[] toDigest = BuildContentBytes(); byte[] C = new byte[128 / 8]; mac.BlockUpdate(toDigest, 0, toDigest.Length); mac.DoFinal(C, 0); byte[] rgbResult = new byte[cbitTag / 8]; Array.Copy(C, 0, rgbResult, 0, cbitTag / 8); return(rgbResult); }
public bool Validate(byte[] content, byte[] msgAttributes) { CBORObject alg = null; // Get the set algorithm or infer one byte[] bytesToBeSigned = toBeSigned(content, msgAttributes); alg = FindAttribute(HeaderKeys.Algorithm); if (alg == null) { throw new Exception("No Signature algorithm known"); } IDigest digest; IDigest digest2; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "PS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; default: throw new Exception("Unknown signature algorithm"); } } else if (alg.Type == CBORType.Number) { 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; default: throw new CoseException("Unknown signature algorith"); } } else { throw new CoseException("Algorthm incorrectly encoded"); } if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "PS384": { 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, Message.GetPRNG()); signer.Init(true, param); signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(signer.VerifySignature(rgbSignature)); } default: throw new CoseException("Unknown Algorithm"); } } else if (alg.Type == CBORType.Number) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.RSA_PSS_256: 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, Message.GetPRNG()); signer.Init(true, param); signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(signer.VerifySignature(rgbSignature)); } case AlgorithmValuesInt.ECDSA_256: case AlgorithmValuesInt.ECDSA_384: case AlgorithmValuesInt.ECDSA_512: { 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); ECPoint point = keyToSign.GetPoint(); ECPublicKeyParameters param = new ECPublicKeyParameters(point, parameters); ECDsaSigner ecdsa = new ECDsaSigner(); ecdsa.Init(false, param); BigInteger r = new BigInteger(1, rgbSignature, 0, rgbSignature.Length / 2); BigInteger s = new BigInteger(1, rgbSignature, rgbSignature.Length / 2, rgbSignature.Length / 2); return(ecdsa.VerifySignature(digestedMessage, r, s)); } default: throw new CoseException("Unknown Algorithm"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } }
public bool Validate(Key recipientReceiver) { byte[] rgbKey = null; int cbitKey; if (recipientReceiver[CoseKeyKeys.KeyType].AsInt32() != (int)GeneralValuesInt.KeyType_Octet) { throw new CoseException("Key type not octet"); } rgbKey = recipientReceiver[CoseKeyParameterKeys.Octet_k].GetByteString(); CBORObject alg = FindAttribute(COSE.HeaderKeys.Algorithm); 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 Exception("MAC algorithm is not recognized"); } } else if (alg.Type == CBORType.Number) { 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 Exception("MAC algorithm not recognized" + alg.AsInt32()); } } else { throw new CoseException("Algorithm incorrectly encoded"); } if (rgbKey == null) { throw new CoseException("No Key Provided"); } byte[] rgbCheck; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "AES-CMAC-128/64": case "AES-CMAC-256/64": rgbCheck = AES_CMAC(alg, rgbKey); break; default: throw new Exception("MAC algorithm is not recognized"); } } else if (alg.Type == CBORType.Number) { 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: rgbCheck = HMAC(alg, rgbKey); 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: rgbCheck = AES_CBC_MAC(alg, rgbKey); break; default: throw new Exception("MAC algorithm not recognized" + alg.AsInt32()); } } else { throw new CoseException("Algorithm incorrectly encoded"); } bool fReturn = true; for (int i = 0; i < rgbCheck.Length; i++) { fReturn &= (rgbTag[i] == rgbCheck[i]); } return(fReturn); }
/// <summary> /// Compute and derive the keys based on the input data /// </summary> /// <param name="keys">Public and Private DH keys to use for creating shared secret</param> /// <param name="salt">A shared symmetric key if one exists</param> /// <param name="otherData">SuppPubInfo other data bytes - changes for each message</param> /// <param name="algAEAD">Symmetric algorithm for encryption</param> /// <returns>array of two byte arrays. The first is the key, the second is the IV</returns> protected static byte[][] _DeriveKeys(OneKey[] keys, byte[] salt, byte[] otherData, CBORObject algAEAD) { int cbitKey = 0; int cbitIV = 0; byte[] secret = ECDH_GenerateSecret(keys); if (algAEAD.Type == CBORType.Number) { switch ((AlgorithmValuesInt)algAEAD.AsInt32()) { case AlgorithmValuesInt.AES_CCM_64_64_128: cbitKey = 128; cbitIV = 58; break; default: throw new Exception("Unknown Algorithm"); } } else if (algAEAD.Type == CBORType.TextString) { switch (algAEAD.AsString()) { case "EDHOC OSCOAP Master Secret": cbitKey = 128; break; case "EDHOC OSCOAP Master Salt": cbitKey = 64; break; default: throw new Exception("Unknown Algorithm"); } } else { throw new Exception("Internal Error"); } CBORObject partyInfo; partyInfo = CBORObject.NewArray(); partyInfo.Add(CBORObject.Null); partyInfo.Add(CBORObject.Null); partyInfo.Add(CBORObject.Null); CBORObject context = CBORObject.NewArray(); context.Add(algAEAD); // Alg context.Add(partyInfo); // Party U context.Add(partyInfo); // Party V CBORObject obj = CBORObject.NewArray(); obj.Add(cbitKey / 8); obj.Add(CBORObject.FromObject(new byte[0])); obj.Add(otherData); context.Add(obj); // SuppPubInfo byte[] rgbContext = context.EncodeToBytes(); byte[][] returnValue = new byte[2][]; returnValue[0] = HKDF(secret, salt, rgbContext, cbitKey, new Sha256Digest()); if (cbitIV > 0) { obj[0] = CBORObject.FromObject(cbitIV / 8); context[0] = CBORObject.FromObject("IV-GENERATION"); returnValue[1] = HKDF(secret, salt, rgbContext, cbitIV, new Sha256Digest()); } return(returnValue); }
private byte[] Sign(byte[] bytesToBeSigned) { CBORObject alg = null; // Get the set algorithm or infer one alg = FindAttribute(HeaderKeys.Algorithm); if (alg == null) { if (keyToSign[CoseKeyKeys.KeyType].Type == CBORType.Number) { switch ((GeneralValuesInt)keyToSign[CoseKeyKeys.KeyType].AsInt32()) { case GeneralValuesInt.KeyType_RSA: alg = CBORObject.FromObject("PS256"); break; case GeneralValuesInt.KeyType_EC2: if (keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Number) { 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; 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"); } objUnprotected.Add(HeaderKeys.Algorithm, alg); } IDigest digest; IDigest digest2; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "PS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; default: throw new Exception("Unknown signature algorithm"); } } else if (alg.Type == CBORType.Number) { 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; default: throw new CoseException("Unknown signature algorith"); } } else { throw new CoseException("Algorthm incorrectly encoded"); } if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "PS384": { 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, Message.GetPRNG()); signer.Init(true, param); signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(signer.GenerateSignature()); } default: throw new CoseException("Unknown Algorithm"); } } else if (alg.Type == CBORType.Number) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.RSA_PSS_256: 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, Message.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: { SecureRandom random = Message.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(keyToSign[CoseKeyParameterKeys.EC_D]), 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); } default: throw new CoseException("Unknown Algorithm"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } }
public static byte[] Sign(byte[] toBeSigned, CBORObject alg, OneKey keyToSign) { IDigest digest = null; IDigest digest2 = null; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "PS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case "HSS-LMS": break; default: throw new Exception("Unknown signature algorithm"); } } 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 signature algorithm"); } } 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(toBeSigned); keyToSign.Replace(CoseKeyParameterKeys.Lms_Private, CBORObject.FromObject(sig.PrivateKey)); return(signBytes); default: throw new CoseException("Unknown Algorithm"); } } 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.GetDigestSize()); ICipherParameters prv = keyToSign.AsPrivateKey(); ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG()); signer.Init(true, param); signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length); return(signer.GenerateSignature()); } case AlgorithmValuesInt.ECDSA_256: case AlgorithmValuesInt.ECDSA_384: case AlgorithmValuesInt.ECDSA_512: { SecureRandom random = Message.GetPRNG(); digest.BlockUpdate(toBeSigned, 0, toBeSigned.Length); byte[] digestedMessage = new byte[digest.GetDigestSize()]; digest.DoFinal(digestedMessage, 0); ICipherParameters privKey = keyToSign.AsPrivateKey(); X9ECParameters p = keyToSign.GetCurve(); 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); } case AlgorithmValuesInt.EdDSA: { ISigner eddsa; if (keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed25519)) { ICipherParameters privKey = keyToSign.AsPrivateKey(); eddsa = new Ed25519Signer(); eddsa.Init(true, privKey); } else if (keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed448)) { ICipherParameters privKey = keyToSign.AsPrivateKey(); eddsa = new Ed448Signer(new byte[0]); eddsa.Init(true, privKey); } else { throw new CoseException("Unrecognized curve"); } eddsa.BlockUpdate(toBeSigned, 0, toBeSigned.Length); return(eddsa.GenerateSignature()); } default: throw new CoseException("Unknown Algorithm"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } }
public static bool Validate(byte[] content, CBORObject alg, OneKey signKey, byte[] rgbSignature) { IDigest digest = null; IDigest digest2 = null; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "HSS-LMS": break; default: throw new Exception("Unknown signature algorithm"); } } 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 signature algorith"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "HSS-LMS": return(HashSig.Validate(content, signKey[CoseKeyParameterKeys.Lms_Public].GetByteString(), rgbSignature)); default: throw new CoseException("Unknown Algorithm"); } } 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.GetDigestSize()); ICipherParameters prv = signKey.AsPublicKey(); ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG()); signer.Init(false, param); signer.BlockUpdate(content, 0, content.Length); return(signer.VerifySignature(rgbSignature)); } case AlgorithmValuesInt.ECDSA_256: case AlgorithmValuesInt.ECDSA_384: case AlgorithmValuesInt.ECDSA_512: { if (signKey.GetKeyType() != GeneralValuesInt.KeyType_EC2) { throw new CoseException("Key is not correctly constructed."); } digest.BlockUpdate(content, 0, content.Length); byte[] digestedMessage = new byte[digest.GetDigestSize()]; digest.DoFinal(digestedMessage, 0); ICipherParameters param = signKey.AsPublicKey(); ECDsaSigner ecdsa = new ECDsaSigner(); ecdsa.Init(false, param); BigInteger r = new BigInteger(1, rgbSignature, 0, rgbSignature.Length / 2); BigInteger s = new BigInteger(1, rgbSignature, rgbSignature.Length / 2, rgbSignature.Length / 2); return(ecdsa.VerifySignature(digestedMessage, r, s)); } #if true case AlgorithmValuesInt.EdDSA: { ISigner eddsa; if (signKey[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed25519)) { ICipherParameters privKey = signKey.AsPublicKey(); eddsa = new Ed25519Signer(); eddsa.Init(false, privKey); } else if (signKey[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed448)) { Ed448PublicKeyParameters privKey = new Ed448PublicKeyParameters(signKey[CoseKeyParameterKeys.OKP_X].GetByteString(), 0); eddsa = new Ed448Signer(new byte[0]); eddsa.Init(false, privKey); } else { throw new CoseException("Unrecognized curve"); } eddsa.BlockUpdate(content, 0, content.Length); return(eddsa.VerifySignature(rgbSignature)); } #endif default: throw new CoseException("Unknown Algorithm"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } }
public void ReverseNegativeKey() { CBORObject result = (CBORObject)_dictionary.Reverse(CBORObject.FromObject(-5), true); Assert.AreEqual(-5, result.AsInt32()); }
public bool Validate(byte[] rgbKey) { int cbitKey; CBORObject alg = FindAttribute(HeaderKeys.Algorithm); 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"); } if (rgbKey == null) { throw new CoseException("No Key Provided"); } if (cbitKey / 8 != rgbKey.Length) { throw new CoseException("Incorrect key length for operation"); } byte[] rgbCheck; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "AES-CMAC-128/64": case "AES-CMAC-256/64": rgbCheck = AES_CMAC(alg, rgbKey); 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: rgbCheck = HMAC(alg, rgbKey); 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: rgbCheck = AES_CBC_MAC(alg, rgbKey); break; default: throw new CoseException("MAC algorithm not recognized " + alg.AsInt32()); } } else { throw new CoseException("Algorithm incorrectly encoded"); } bool fReturn = true; for (int i = 0; i < rgbCheck.Length; i++) { fReturn &= (RgbTag[i] == rgbCheck[i]); } return(fReturn); }
private byte[] AES(CBORObject alg, byte[] K) { GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine(), new BasicGcmMultiplier()); KeyParameter ContentKey; byte[] IV; CBORObject cbor; // The requirements from JWA // IV is 96 bits // Authentication tag is 128 bits // key sizes are 128, 192 and 256 bits IV = new byte[96 / 8]; cbor = FindAttribute(HeaderKeys.IV); if (cbor != null) { if (cbor.Type != CBORType.ByteString) { throw new CoseException("IV is incorrectly formed."); } if (cbor.GetByteString().Length != IV.Length) { throw new CoseException("IV size is incorrect."); } Array.Copy(cbor.GetByteString(), IV, IV.Length); } else { s_PRNG.NextBytes(IV); AddAttribute(HeaderKeys.IV, CBORObject.FromObject(IV), UNPROTECTED); } if (K == null) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.AES_GCM_128: K = new byte[128 / 8]; break; case AlgorithmValuesInt.AES_GCM_192: K = new byte[192 / 8]; break; case AlgorithmValuesInt.AES_GCM_256: K = new byte[256 / 8]; break; default: throw new CoseException("Unsupported algorithm: " + alg); } s_PRNG.NextBytes(K); } ContentKey = new KeyParameter(K); // Build the object to be hashed AeadParameters parameters = new AeadParameters(ContentKey, 128, IV, getAADBytes()); cipher.Init(true, parameters); byte[] C = new byte[cipher.GetOutputSize(rgbContent.Length)]; int len = cipher.ProcessBytes(rgbContent, 0, rgbContent.Length, C, 0); len += cipher.DoFinal(C, len); RgbEncrypted = C; return(K); }
public static void TestNumber(CBORObject o) { if (o.Type != CBORType.Number) { return; } if (o.IsPositiveInfinity() || o.IsNegativeInfinity() || o.IsNaN()) { try { o.AsByte(); Assert.Fail("Should have failed"); } catch (OverflowException) { new Object(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsInt16(); Assert.Fail("Should have failed"); } catch (OverflowException) { new Object(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsInt32(); Assert.Fail("Should have failed"); } catch (OverflowException) { new Object(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsInt64(); Assert.Fail("Should have failed"); } catch (OverflowException) { new Object(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsSingle(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { o.AsDouble(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { o.AsEInteger(); Assert.Fail("Should have failed"); } catch (OverflowException) { new Object(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } return; } try { o.AsSingle(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsDouble(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } }
protected byte[] HMAC(CBORObject alg, byte[] K) { int cbitKey; int cbResult; IDigest digest; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { default: throw new Exception("Unrecognized algorithm"); } } else if (alg.Type == CBORType.Number) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.HMAC_SHA_256: cbitKey = 256; cbResult = 256 / 8; digest = new Sha256Digest(); break; case AlgorithmValuesInt.HMAC_SHA_256_64: cbitKey = 256; digest = new Sha256Digest(); cbResult = 64 / 8; break; case AlgorithmValuesInt.HMAC_SHA_384: cbitKey = 384; digest = new Sha384Digest(); cbResult = cbitKey / 8; break; case AlgorithmValuesInt.HMAC_SHA_512: cbitKey = 512; digest = new Sha512Digest(); cbResult = cbitKey / 8; break; default: throw new CoseException("Unknown or unsupported algorithm"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } if (K == null) { throw new CoseException("No Key value"); } HMac hmac = new HMac(digest); KeyParameter key = new KeyParameter(K); byte[] resBuf = new byte[hmac.GetMacSize()]; byte[] toDigest = BuildContentBytes(); hmac.Init(key); hmac.BlockUpdate(toDigest, 0, toDigest.Length); hmac.DoFinal(resBuf, 0); byte[] rgbOut = new byte[cbResult]; Array.Copy(resBuf, rgbOut, cbResult); return(rgbOut); }
private void AES_CCM_Decrypt(CBORObject alg, byte[] K) { CcmBlockCipher cipher = new CcmBlockCipher(new AesEngine()); KeyParameter ContentKey; int cbitTag; int cbIV; int cbitKey; // Figure out what the correct internal parameters to use are Debug.Assert(alg.Type == CBORType.Integer); switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.AES_CCM_16_64_128: case AlgorithmValuesInt.AES_CCM_64_64_128: cbitKey = 128; cbitTag = 64; break; case AlgorithmValuesInt.AES_CCM_16_128_128: case AlgorithmValuesInt.AES_CCM_64_128_128: cbitKey = 128; cbitTag = 128; break; case AlgorithmValuesInt.AES_CCM_16_64_256: case AlgorithmValuesInt.AES_CCM_64_64_256: cbitKey = 256; cbitTag = 64; break; case AlgorithmValuesInt.AES_CCM_16_128_256: case AlgorithmValuesInt.AES_CCM_64_128_256: cbitKey = 256; cbitTag = 128; break; default: throw new CoseException("Unsupported algorithm: " + alg); } switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.AES_CCM_16_64_128: case AlgorithmValuesInt.AES_CCM_16_64_256: case AlgorithmValuesInt.AES_CCM_16_128_128: case AlgorithmValuesInt.AES_CCM_16_128_256: cbIV = 15 - 2; break; case AlgorithmValuesInt.AES_CCM_64_64_128: case AlgorithmValuesInt.AES_CCM_64_64_256: case AlgorithmValuesInt.AES_CCM_64_128_256: case AlgorithmValuesInt.AES_CCM_64_128_128: cbIV = 15 - 8; break; default: throw new CoseException("Unsupported algorithm: " + alg); } // The requirements from JWA byte[] IV = new byte[cbIV]; CBORObject cbor = FindAttribute(HeaderKeys.IV); if (cbor != null) { if (cbor.Type != CBORType.ByteString) { throw new CoseException("IV is incorrectly formed."); } if (cbor.GetByteString().Length > IV.Length) { throw new CoseException("IV is too long."); } Array.Copy(cbor.GetByteString(), 0, IV, 0, IV.Length); } else { s_PRNG.NextBytes(IV); AddAttribute(HeaderKeys.IV, CBORObject.FromObject(IV), UNPROTECTED); } if (K == null) { throw new CoseException("Internal error"); } if (K.Length != cbitKey / 8) { throw new CoseException("Incorrect key length"); } ContentKey = new KeyParameter(K); // Build the object to be hashed AeadParameters parameters = new AeadParameters(ContentKey, cbitTag, IV, getAADBytes()); cipher.Init(false, parameters); byte[] C = new byte[cipher.GetOutputSize(RgbEncrypted.Length)]; int len = cipher.ProcessBytes(RgbEncrypted, 0, RgbEncrypted.Length, C, 0); len += cipher.DoFinal(C, len); rgbContent = C; }
private byte[] ChaCha20_Poly1305(CBORObject alg, byte[] K) { ChaCha20Poly1305 cipher = new ChaCha20Poly1305(); KeyParameter ContentKey; int cbitTag = 128; // The requirements from JWA // IV is 96 bits // Authentication tag is 128 bits // key size is 256 bits byte[] IV = new byte[96 / 8]; CBORObject cbor = FindAttribute(HeaderKeys.IV); if (cbor != null) { if (cbor.Type != CBORType.ByteString) { throw new CoseException("IV is incorrectly formed."); } if (cbor.GetByteString().Length > IV.Length) { throw new CoseException("IV is too long."); } Array.Copy(cbor.GetByteString(), 0, IV, IV.Length - cbor.GetByteString().Length, cbor.GetByteString().Length); } else { s_PRNG.NextBytes(IV); AddAttribute(HeaderKeys.IV, CBORObject.FromObject(IV), UNPROTECTED); } if (K == null) { Debug.Assert(alg.Type == CBORType.Number); switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.ChaCha20_Poly1305: K = new byte[256 / 8]; cbitTag = 128; break; default: throw new CoseException("Unsupported algorithm: " + alg); } s_PRNG.NextBytes(K); } // Generate key ContentKey = new KeyParameter(K); // Build the object to be hashed byte[] aad = getAADBytes(); AeadParameters parameters = new AeadParameters(ContentKey, cbitTag, IV, aad); cipher.Init(true, parameters); byte[] C = new byte[cipher.GetOutputSize(rgbContent.Length)]; int len = cipher.ProcessBytes(rgbContent, 0, rgbContent.Length, C, 0); len += cipher.DoFinal(C, len); RgbEncrypted = C; return(K); }
#pragma warning disable CS0618 public static void TestNumber(CBORObject o) { if (o.Type != CBORType.Number) { return; } if (o.IsPositiveInfinity() || o.IsNegativeInfinity() || o.IsNaN()) { try { o.AsByte(); Assert.Fail("Should have failed"); } catch (OverflowException) { // NOTE: Intentionally empty } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsInt16(); Assert.Fail("Should have failed"); } catch (OverflowException) { // NOTE: Intentionally empty } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsInt32(); Assert.Fail("Should have failed"); } catch (OverflowException) { // NOTE: Intentionally empty } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsInt64(); Assert.Fail("Should have failed"); } catch (OverflowException) { // NOTE: Intentionally empty } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsSingle(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { o.AsDouble(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { o.AsEInteger(); Assert.Fail("Should have failed"); } catch (OverflowException) { // NOTE: Intentionally empty } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } return; } try { o.AsSingle(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } try { o.AsDouble(); } catch (Exception ex) { Assert.Fail("Object: " + o + ", " + ex); throw new InvalidOperationException(String.Empty, ex); } }
private string _PrintCBOR(CBORObject obj, int iLevel) { string strOut = ""; string strLine; string pad = ((String)" ").Substring(0, iLevel); switch (obj.Type) { case CBORType.Array: strOut = "[\n"; for (int i = 0; i < obj.Count; i++) { strOut += pad + " " + _PrintCBOR(obj[i], iLevel + 1) + ",\n"; } strOut += pad + "]"; break; case CBORType.Map: strOut = "{\n"; foreach (CBORObject key in obj.Keys) { strOut += pad + " " + _PrintCBOR(key, 0) + " : " + _PrintCBOR(obj[key], iLevel + 1) + ",\n"; } strOut += pad + "}"; break; case CBORType.ByteString: strLine = pad + "h'"; byte[] rgb = obj.GetByteString(); byte[] rgb2 = new byte[1]; foreach (byte b in rgb) { if (strLine.Length > 66) { if (strOut == "") { strOut = strLine.Substring(iLevel) + "\n"; } else { strOut += strLine + "\n"; } strLine = pad + " "; } rgb2[0] = b; strLine += BitConverter.ToString(rgb2); } strOut += strLine; strOut += "'"; break; case CBORType.Integer: strOut = obj.AsInt32().ToString(); break; case CBORType.SimpleValue: if (obj.IsNull) { return("null"); } return(obj.Type.ToString()); case CBORType.TextString: strOut = "\"" + obj.AsString() + "\""; break; default: strOut = obj.Type.ToString(); break; } return(strOut); }