public override CBORObject Encode() { CBORObject obj; obj = CBORObject.NewArray(); if ((ProtectedMap != null) && (ProtectedMap.Count > 0)) { obj.Add(ProtectedMap.EncodeToBytes()); } else { obj.Add(new byte[0]); } ProtectedBytes = obj[0].GetByteString(); ProcessCounterSignatures(); if ((UnprotectedMap == null) || (UnprotectedMap.Count == 0)) { obj.Add(CBORObject.NewMap()); } else { obj.Add(UnprotectedMap); // Add unprotected attributes } obj.Add(rgbContent); PerformSignature(); obj.Add(_rgbSignature); return(obj); }
private byte[] BuildContentBytes() #endif { CBORObject obj = CBORObject.NewArray(); obj.Add(_strContext); if (ProtectedBytes == null) { if (ProtectedMap.Count > 0) { ProtectedBytes = ProtectedMap.EncodeToBytes(); } else { ProtectedBytes = new byte[0]; } } obj.Add(ProtectedBytes); if (ExternalData != null) { obj.Add(CBORObject.FromObject(ExternalData)); } else { obj.Add(CBORObject.FromObject(new byte[0])); } obj.Add(rgbContent); return(obj.EncodeToBytes()); }
public void PerformSignature() { CBORObject cborProtected = CBORObject.FromObject(new byte[0]); if ((ProtectedMap != null) && (ProtectedMap.Count > 0)) { byte[] rgb = ProtectedMap.EncodeToBytes(); cborProtected = CBORObject.FromObject(rgb); } if (_rgbSignature == null) { CBORObject signObj = CBORObject.NewArray(); signObj.Add(_context); signObj.Add(cborProtected); signObj.Add(ExternalData); // External AAD signObj.Add(rgbContent); _rgbSignature = _Sign(toBeSigned()); #if FOR_EXAMPLES m_toBeSigned = signObj.EncodeToBytes(); #endif } }
public CBORObject EncodeToCBORObject(byte[] bodyAttributes, byte[] body) { CBORObject obj = CBORObject.NewArray(); CBORObject cborProtected = CBORObject.FromObject(new byte[0]); if ((ProtectedMap != null) && (ProtectedMap.Count > 0)) { byte[] rgb = ProtectedMap.EncodeToBytes(); cborProtected = CBORObject.FromObject(rgb); } ProtectedBytes = cborProtected.GetByteString(); obj.Add(cborProtected); if (rgbSignature == null) { rgbSignature = Sign(toBeSigned(body, bodyAttributes)); } ProcessCounterSignatures(); if ((UnprotectedMap == null)) { obj.Add(CBORObject.NewMap()); } else { obj.Add(UnprotectedMap); // Add unprotected attributes } obj.Add(rgbSignature); return(obj); }
protected byte[] toBeSigned(byte[] rgbContent, byte[] bodyAttributes) { CBORObject cborProtected = CBORObject.FromObject(new byte[0]); if ((ProtectedMap != null) && (ProtectedMap.Count > 0)) { byte[] rgb = ProtectedMap.EncodeToBytes(); cborProtected = CBORObject.FromObject(rgb); } if (rgbContent == null) { rgbContent = new byte[0]; } CBORObject signObj = CBORObject.NewArray(); signObj.Add(context); signObj.Add(bodyAttributes); signObj.Add(cborProtected); signObj.Add(ExternalData); signObj.Add(rgbContent); #if FOR_EXAMPLES m_toBeSigned = signObj.EncodeToBytes(); #endif return(signObj.EncodeToBytes()); }
/// <summary> /// Encode the COSE Encrypt0 item to a CBOR tree. /// <see cref="Encrypt"/> must be done prior to calling this function. /// </summary> /// <returns></returns> public override CBORObject Encode() { CBORObject cbor; if (RgbEncrypted == null) { throw new CoseException("Must call Encrypt first"); } ProcessCounterSignatures(); cbor = CBORObject.NewArray(); if (ProtectedMap.Count > 0) { cbor.Add(ProtectedMap.EncodeToBytes()); } else { cbor.Add(CBORObject.FromObject(new byte[0])); } cbor.Add(UnprotectedMap); // Add unprotected attributes if (m_emitContent) { cbor.Add(RgbEncrypted); // Add ciphertext } else { cbor.Add(CBORObject.Null); } return(cbor); }
public override CBORObject Encode() { CBORObject obj; if (RgbTag == null) { MAC(); } obj = CBORObject.NewArray(); if (ProtectedMap.Count > 0) { obj.Add(ProtectedMap.EncodeToBytes()); } else { obj.Add(new byte[0]); } if (UnprotectedMap.Count > 0) { obj.Add(UnprotectedMap); // Add unprotected attributes } else { obj.Add(CBORObject.NewMap()); } obj.Add(rgbContent); // Add ciphertext obj.Add(RgbTag); if ((!m_forceArray) && (_recipientList.Count == 1)) { CBORObject recipient = _recipientList[0].Encode(); for (int i = 0; i < recipient.Count; i++) { obj.Add(recipient[i]); } } else if (_recipientList.Count > 0) { CBORObject recipients = CBORObject.NewArray(); foreach (Recipient key in _recipientList) { recipients.Add(key.Encode()); } obj.Add(recipients); } else { obj.Add(null); // No recipients - set to null } return(obj); }
public byte[] getAADBytes() { CBORObject obj = CBORObject.NewArray(); obj.Add(_context); if (ProtectedMap.Count == 0) { ProtectedBytes = new byte[0]; } else { ProtectedBytes = ProtectedMap.EncodeToBytes(); } obj.Add(ProtectedBytes); obj.Add(CBORObject.FromObject(ExternalData)); // Console.WriteLine("COSE AAD = " + BitConverter.ToString(obj.EncodeToBytes())); return(obj.EncodeToBytes()); }
private byte[] toBeSigned() { CBORObject cborProtected = CBORObject.FromObject(new byte[0]); if ((ProtectedMap != null) && (ProtectedMap.Count > 0)) { byte[] rgb = ProtectedMap.EncodeToBytes(); cborProtected = CBORObject.FromObject(rgb); } CBORObject signObj = CBORObject.NewArray(); signObj.Add(_context); signObj.Add(cborProtected); signObj.Add(ExternalData); // External AAD signObj.Add(rgbContent); #if FOR_EXAMPLES m_toBeSigned = signObj.EncodeToBytes(); #endif return(signObj.EncodeToBytes()); }
public CBORObject EncodeToJSON(byte[] body) { CBORObject obj = CBORObject.NewMap(); if (protectedB64 != null) { obj.Add("protected", protectedB64); } else if (ProtectedMap.Count > 0) { protectedB64 = Message.base64urlencode(Encoding.UTF8.GetBytes(JSON.ToJsonString(ProtectedMap))); obj.Add("protected", protectedB64); } if (UnprotectedMap.Count > 0) { obj.Add("header", UnprotectedMap); // Add unprotected attributes } String str = ""; if (ProtectedMap.ContainsKey("b64") && ProtectedMap["b64"].AsBoolean() == false) { str += protectedB64 + "." + Encoding.UTF8.GetString(body); } else { str += protectedB64 + "." + Message.base64urlencode(body); } #if DEBUG ToBeSigned = str; #endif obj.Add("signature", Message.base64urlencode(Sign(Encoding.UTF8.GetBytes(str)))); return(obj); }
public override CBORObject Encode() { CBORObject obj; if (RgbTag == null) { throw new CoseException("Must call Compute before encoding"); } ProcessCounterSignatures(); obj = CBORObject.NewArray(); if (ProtectedMap.Count > 0) { obj.Add(ProtectedMap.EncodeToBytes()); } else { obj.Add(new byte[0]); } if (UnprotectedMap.Count > 0) { obj.Add(UnprotectedMap); // Add unprotected attributes } else { obj.Add(CBORObject.NewMap()); } obj.Add(rgbContent); // Add ciphertext obj.Add(RgbTag); return(obj); }
private void AES_CCM(byte[] k) { CcmBlockCipher cipher = new CcmBlockCipher(new AesEngine()); KeyParameter contentKey; int cbitTag = 64; // 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]; s_PRNG.NextBytes(_iv); contentKey = new KeyParameter(k); // Build the object to be hashed byte[] a = new byte[0]; if (ProtectedMap != null) { a = Encoding.UTF8.GetBytes(ProtectedMap.ToString()); } 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); cipher.DoFinal(c, len); Array.Resize(ref c, c.Length - (128 / 8) + (cbitTag / 8)); _RgbEncrypted = c; }
public override CBORObject Encode() { CBORObject obj; byte[] rgbProtected; obj = CBORObject.NewArray(); if ((ProtectedMap != null) && (ProtectedMap.Count > 0)) { rgbProtected = ProtectedMap.EncodeToBytes(); obj.Add(rgbProtected); } else { rgbProtected = new byte[0]; obj.Add(rgbProtected); } if (CounterSignerList.Count() != 0) { if (CounterSignerList.Count() == 1) { AddAttribute(HeaderKeys.CounterSignature, CounterSignerList[0].EncodeToCBORObject(rgbProtected, rgbContent), UNPROTECTED); } else { foreach (CounterSignature sig in CounterSignerList) { sig.EncodeToCBORObject(rgbProtected, rgbContent); } } } if ((UnprotectedMap == null) || (UnprotectedMap.Count == 0)) { obj.Add(CBORObject.NewMap()); } else { obj.Add(UnprotectedMap); // Add unprotected attributes } obj.Add(rgbContent); if ((signerList.Count == 1) && !m_forceArray) { CBORObject recipient = signerList[0].EncodeToCBORObject(obj[0].EncodeToBytes(), rgbContent); for (int i = 0; i < recipient.Count; i++) { obj.Add(recipient[i]); } } else if (signerList.Count > 0) { CBORObject signers = CBORObject.NewArray(); foreach (Signer key in signerList) { signers.Add(key.EncodeToCBORObject(rgbProtected, rgbContent)); } obj.Add(signers); } else { obj.Add(null); // No recipients - set to null } return(obj); }
/// <summary> /// Encrypt the message based on attributes and recipients. /// </summary> public virtual void Encrypt() { string alg = null; // Get the algorithm we are using - the default is AES GCM try { alg = FindAttribute("enc").AsString(); } catch { foreach (Recipient r in RecipientList) { CBORObject alg2 = r.FindAttribute("enc"); if (alg2 != null) { if (alg2.Type != CBORType.TextString || (alg != null && alg != alg2.AsString())) { throw new JoseException("Multiple content encryption algorithms have been specified."); } alg = alg2.AsString(); } } if (alg == null) { throw new JoseException("Content encryption algorithm has not been specified."); } } byte[] contentKey = null; // Determine if we are doing a direct encryption int recipientTypes = 0; if (RecipientList.Count == 0) { throw new JoseException("Must have at least one recipient for the message"); } foreach (Recipient key in RecipientList) { switch (key.RecipientType) { case RecipientType.Direct: case RecipientType.KeyAgreeDirect: if ((recipientTypes & 1) != 0) { throw new JoseException("It is not legal to have two direct recipients in a message"); } recipientTypes |= 1; contentKey = key.GetKey(alg, this); break; default: recipientTypes |= 2; break; } } if (recipientTypes == 3) { throw new JoseException("It is not legal to mix direct and indirect recipients in a message"); } if (contentKey == null) { switch (alg) { case "A128GCM": case "AES-128-CCM-64": contentKey = new byte[128 / 8]; break; case "A192GCM": case "AES192GCM": contentKey = new byte[192 / 8]; break; case "A256GCM": case "AES256GCM": contentKey = new byte[256 / 8]; break; case "A128CBC-HS256": contentKey = new byte[2 * 128 / 8]; break; case "A192CBC-HS256": contentKey = new byte[2 * 192 / 8]; break; case "A256CBC-HS256": contentKey = new byte[2 * 256 / 8]; break; default: throw new JoseException($"Unrecognized content encryption algorithm '{alg}'"); } s_PRNG.NextBytes(contentKey); } foreach (Recipient key in RecipientList) { key.SetContent(contentKey); key.Encrypt(this); } // Encode the protected attributes if there are any if (ProtectedMap.Count > 0) { _strProtected = base64urlencode(Encoding.UTF8.GetBytes(ProtectedMap.ToString())); } byte[] saveContent = payload; if (ProtectedMap.ContainsKey("zip")) { MemoryStream stm2 = new MemoryStream(); DeflateStream zipStm = new DeflateStream(stm2, CompressionMode.Compress); zipStm.Write(payload, 0, payload.Length); zipStm.Close(); payload = stm2.GetBuffer(); } switch (alg) { case "A128GCM": case "A192GCM": case "A256GCM": AES_GCM_Encrypt(contentKey); break; case "AES-128-CCM-64": AES_CCM(contentKey); break; case "A128CBC-HS256": case "A192CBC-HS256": case "A256CBC-HS256": AES_CBC_MAC_Encrypt(alg, contentKey); break; default: throw new JoseException("Internal Error: We should never get here."); } payload = saveContent; }
/// <inheritdoc /> protected override string InternalEncodeCompressed() { CBORObject obj3; CBORObject objRecip = null; string str = ""; if (RecipientList.Count() != 1) { throw new JoseException("Compact encoding cannot have more than one recipient"); } if (_Aad != null) { throw new JoseException("Compact encoding cannot have additional authenticated data"); } if (RecipientList[0].UnprotectedMap.Count != 0) { if (_RgbEncrypted == null) { foreach (CBORObject o in RecipientList[0].UnprotectedMap.Keys) { ProtectedMap.Add(o, RecipientList[0].UnprotectedMap[o]); } RecipientList[0].UnprotectedMap.Clear(); } } ForceArray(true); obj3 = EncodeToJSON(); if (obj3.ContainsKey("recipients")) { objRecip = obj3["recipients"][0]; } if (obj3.ContainsKey("aad")) { throw new JoseException("Compact encoding cannot have additional authenticated data"); } if (objRecip != null && objRecip.ContainsKey("header")) { throw new JoseException("Compact encoding cannot have recipient header data"); } if (obj3.ContainsKey("protected")) { str += obj3["protected"].AsString(); } str += "."; if (obj3.ContainsKey("unprotected")) { throw new JoseException("Compact encoding cannot have unprotected attributes"); } if (objRecip != null && objRecip.ContainsKey("encrypted_key")) { str += objRecip["encrypted_key"].AsString(); } str += "."; if (obj3.ContainsKey("iv")) { str += obj3["iv"].AsString(); } str += "."; if (obj3.ContainsKey("ciphertext")) { str += obj3["ciphertext"].AsString(); } str += "."; if (obj3.ContainsKey("tag")) { str += obj3["tag"].AsString(); } return(str); }
/// <inheritdoc /> protected override CBORObject InternalEncodeToJSON(bool fCompact) { CBORObject obj = CBORObject.NewMap(); if (_RgbEncrypted == null) { Encrypt(); } if (ProtectedMap.Count > 0) { obj.Add("protected", base64urlencode(Encoding.UTF8.GetBytes(ProtectedMap.ToString()))); } if (UnprotectedMap.Count > 0) { obj.Add("unprotected", UnprotectedMap); // Add unprotected attributes } if (_iv != null) { obj.Add("iv", base64urlencode(_iv)); // Add iv } if (_Aad != null) { obj.Add("aad", Encoding.UTF8.GetString(_Aad)); } if (_RgbEncrypted != null) { obj.Add("ciphertext", base64urlencode(_RgbEncrypted)); // Add ciphertext } obj.Add("tag", base64urlencode(_Tag)); if (RecipientList.Count > 0) { CBORObject recipients = CBORObject.NewArray(); foreach (Recipient key in RecipientList) { CBORObject j = key.EncodeToJSON(); if ((j != null) && (j.Count != 0)) { recipients.Add(j); } } if (fCompact) { if (recipients.Count != 1) { throw new JoseException("Compact encoding must be for one recipient"); } if (recipients[0].ContainsKey("encrypted_key")) { obj.Add("encrypted_key", recipients[0]["encrypted_key"]); } if (recipients[0].ContainsKey("header")) { obj.Add("header", recipients[0]["header"]); } } else { if (recipients.Count > 0) { obj.Add("recipients", recipients); } } } else { throw new JoseException("Must have one or more recipients"); } return(obj); }
public bool Verify(SignMessage msg) { string alg = FindAttribute("alg").AsString(); JWK key = keyToSign; IDigest digest; IDigest digest2; switch (alg) { case "RS256": case "ES256": case "PS256": case "HS256": digest = new Sha256Digest(); digest2 = new Sha256Digest(); break; case "RS384": case "ES384": case "PS384": case "HS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case "RS512": case "ES512": case "PS512": case "HS512": digest = new Sha512Digest(); digest2 = new Sha512Digest(); break; case "EdDSA": digest = null; digest2 = null; break; default: throw new JoseException("Unknown signature algorithm"); } // byte[] toBeSigned; string str = ""; string body = Encoding.UTF8.GetString(msg.payloadB64); if (ProtectedMap.ContainsKey("b64") && ProtectedMap["b64"].AsBoolean() == false) { str += protectedB64 + "." + body; } else { str += protectedB64 + "." + body; } toBeSigned = Encoding.UTF8.GetBytes(str); switch (alg) { case "RS256": case "RS384": case "RS512": { if (key.AsString("kty") != "RSA") { throw new JoseException("Wrong Key"); } RsaDigestSigner signer = new RsaDigestSigner(digest); RsaKeyParameters pub = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e")); signer.Init(false, pub); signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length); if (!signer.VerifySignature(signature)) { throw new JoseException("Message failed to verify"); } } break; case "PS256": case "PS384": case "PS512": { PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest2.GetDigestSize()); RsaKeyParameters pub = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e")); signer.Init(false, pub); signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length); if (!signer.VerifySignature(signature)) { throw new JoseException("Message failed to verify"); } } break; case "ES256": case "ES384": case "ES512": { digest.BlockUpdate(toBeSigned, 0, toBeSigned.Length); byte[] o1 = new byte[digest.GetDigestSize()]; digest.DoFinal(o1, 0); if (key.AsString("kty") != "EC") { throw new JoseException("Wrong Key Type"); } ICipherParameters pubKey = keyToSign.AsPublicKey(); ECDsaSigner ecdsa = new ECDsaSigner(); ecdsa.Init(false, pubKey); BigInteger r = new BigInteger(1, signature, 0, signature.Length / 2); BigInteger s = new BigInteger(1, signature, signature.Length / 2, signature.Length / 2); if (!ecdsa.VerifySignature(o1, r, s)) { throw new JoseException("Signature did not validate"); } } break; case "HS256": case "HS384": case "HS512": { HMac hmac = new HMac(digest); KeyParameter K = new KeyParameter(Message.base64urldecode(key.AsString("k"))); hmac.Init(K); hmac.BlockUpdate(toBeSigned, 0, toBeSigned.Length); byte[] resBuf = new byte[hmac.GetMacSize()]; hmac.DoFinal(resBuf, 0); bool fVerify = true; for (int i = 0; i < resBuf.Length; i++) { if (resBuf[i] != signature[i]) { fVerify = false; } } if (!fVerify) { throw new JoseException("Signature did not validate"); } } break; case "EdDSA": { ISigner eddsa; if (key.AsString("kty") != "OKP") { throw new JoseException("Wrong Key Type"); } switch (key.AsString("crv")) { case "Ed25519": { Ed25519PublicKeyParameters privKey = new Ed25519PublicKeyParameters(key.AsBytes("X"), 0); eddsa = new Ed25519Signer(); eddsa.Init(false, privKey); eddsa.BlockUpdate(toBeSigned, 0, toBeSigned.Length); if (!eddsa.VerifySignature(signature)) { throw new JoseException("Signature did not validate"); } break; } default: throw new JoseException("Unknown algorithm"); } break; } default: throw new JoseException("Unknown algorithm"); } return(true); }