/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package COSE; import org.junit.*; import com.upokecenter.cbor.CBORObject; import com.upokecenter.cbor.CBORType; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Base64; import java.util.Collection; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.*; /** * * @author jimsch */ @RunWith(Parameterized.class) public class RegressionTest extends TestBase { @Parameters(name = "{index}: {0})") public static Collection data() { return Arrays.asList(new Object[] { "Examples/countersign", "Examples/countersign0", "Examples/eddsa-examples", "Examples/aes-ccm-examples", "Examples/aes-gcm-examples", "Examples/aes-wrap-examples", "Examples/cbc-mac-examples", "Examples/ecdh-direct-examples", "Examples/ecdh-wrap-examples", "Examples/ecdsa-examples", "Examples/encrypted-tests", "Examples/enveloped-tests", "Examples/hkdf-hmac-sha-examples", "Examples/hmac-examples", "Examples/mac-tests", "Examples/mac0-tests", "Examples/sign-tests", "Examples/sign1-tests", "Examples/RFC8152", "Examples/rsa-pss-examples", "Examples/CWT" }); } @Parameter // first data value (0) is default public /* NOT private */ String directoryName; public int CFails = 0; @Test public void ProcessDirectory() { CFails=0; File directory = new File(directoryName); if (!directory.isDirectory()) { directory = new File("D:\\Projects\\cose\\" + directoryName); } File[] contents = directory.listFiles(); org.junit.Assert.assertNotNull(directoryName, contents); for ( File f : contents) { ProcessFile(f.getAbsolutePath()); } assertEquals(0, CFails); } public void ProcessFile(String test) { if (!test.endsWith(".json")) return; try { int fails = CFails; System.out.print("Check: " + test); InputStream str = new FileInputStream(test); CBORObject foo = CBORObject.ReadJSON(str); ProcessJSON(foo); if (fails == CFails) System.out.print("... PASS\n"); else System.out.print("... FAIL\n"); } catch (CoseException e) { if (e.getMessage().equals("Unsupported key size") || e.getMessage().equals("Unsupported Algorithm")) { System.out.print("... SKIP\nException " + e + "\n"); } else { System.out.print("... FAIL\nException " + e + "\n"); CFails++; } } catch(Exception e) { System.out.print("... FAIL\nException " + e + "\n"); CFails++; } } public void ProcessJSON(CBORObject control) throws CoseException, IllegalStateException, Exception { CBORObject input = control.get("input"); if (input.ContainsKey("mac0")) { VerifyMac0Test(control); BuildMac0Test(control); } else if (input.ContainsKey("mac")) { VerifyMacTest(control); BuildMacTest(control); } else if (input.ContainsKey("encrypted")) { VerifyEncryptTest(control); BuildEncryptTest(control); } else if (input.ContainsKey("enveloped")) { VerifyEnvelopedTest(control); BuildEnvelopedTest(control); } else if (input.ContainsKey("sign")) { ValidateSigned(control); BuildSignedMessage(control); } else if (input.ContainsKey("sign0")) { ValidateSign0(control); BuildSign0Message(control); } } public void BuildEncryptTest(CBORObject cnControl) throws CoseException, IllegalStateException, Exception { CBORObject cnFail = cnControl.get("fail"); if ((cnFail != null) && cnFail.AsBoolean()) return; CBORObject cnInput = cnControl.get("input"); CBORObject cnEncrypt = cnInput.get("encrypted"); Encrypt0Message msg = new Encrypt0Message(); CBORObject cn = cnInput.get("plaintext"); if (cn == null) { cn = cnInput.get("plaintext_hex"); msg.SetContent(hexStringToByteArray(cn.AsString())); } else { msg.SetContent(cn.AsString()); } SetSendingAttributes(msg, cnEncrypt, true); if (cnEncrypt.ContainsKey("countersign0")) { AddCounterSignature0(msg, cnEncrypt.get("countersign0")); } if (cnEncrypt.ContainsKey("countersign")) { AddCounterSignature(msg, cnEncrypt.get("countersign")); } CBORObject cnRecipients = cnEncrypt.get("recipients"); cnRecipients = cnRecipients.get(0); OneKey cnKey = BuildKey(cnRecipients.get("key"), true); CBORObject kk = cnKey.get(CBORObject.FromObject(-1)); msg.encrypt(kk.GetByteString()); byte[] rgb = msg.EncodeToBytes(); _VerifyEncrypt(cnControl, rgb); } public void VerifyEncryptTest(CBORObject control) throws CoseException { String strExample = control.get("output").get("cbor").AsString(); byte[] rgb = hexStringToByteArray(strExample); _VerifyEncrypt(control, rgb); } public void _VerifyEncrypt(CBORObject control, byte[] rgbData) throws CoseException { CBORObject cnInput = control.get("input"); boolean fFail = false; boolean fFailBody = false; CBORObject cnFail = control.get("fail"); if ((cnFail != null) && (cnFail.getType() == CBORType.Boolean) && cnFail.AsBoolean()) { fFailBody = true; } try { Message msg; try { msg = Message.DecodeFromBytes(rgbData, MessageTag.Encrypt0); } catch (Exception e) { if (!fFailBody && ((cnFail == null) || !cnFail.AsBoolean())) CFails ++; throw new Exception(); } Encrypt0Message enc0 = (Encrypt0Message)msg; CBORObject cnEncrypt = cnInput.get("encrypted"); SetReceivingAttributes(msg, cnEncrypt); CBORObject cnRecipients = cnEncrypt.get("recipients"); cnRecipients = cnRecipients.get(0); OneKey cnKey = BuildKey(cnRecipients.get("key"), true); CBORObject kk = cnKey.get(CBORObject.FromObject(-1)); cnFail = cnRecipients.get("fail"); try { byte[] rgbContent = enc0.decrypt(kk.GetByteString()); if ((cnFail != null) && !cnFail.AsBoolean()) CFails++; byte[] oldContent; CBORObject cnOldContent = cnInput.get("plaintext"); if (cnOldContent == null) { cnOldContent = cnInput.get("plaintext_hex"); oldContent = hexStringToByteArray(cnOldContent.AsString()); } else { oldContent = cnInput.get("plaintext").AsString().getBytes(StandardCharsets.UTF_8); } assertArrayEquals(oldContent, rgbContent); } catch(CoseException e) { if (e.getMessage() == "Unsupported key size") { throw e; } if (!fFailBody && ((cnFail == null) || !cnFail.AsBoolean())) CFails ++; } catch (Exception e) { if (!fFailBody && ((cnFail == null) || !cnFail.AsBoolean())) CFails ++; } CBORObject cnCounter = cnEncrypt.get("countersign0"); if (cnCounter != null) { CheckCounterSignature0(msg, cnCounter); } cnCounter = cnEncrypt.get("countersign"); if (cnCounter != null) { CheckCounterSignatures(msg, cnCounter); } } catch (CoseException e) { throw e; } catch (Exception e) { if (!fFailBody) CFails++; } } void BuildMacTest(CBORObject cnControl) throws Exception { int iRecipient; // // We don't run this for all control sequences - skip those marked fail. // if (HasFailMarker(cnControl)) return; MACMessage hEncObj = new MACMessage(); CBORObject cnInputs = cnControl.get("input"); CBORObject cnEnveloped = cnInputs.get("mac"); CBORObject cnContent = cnInputs.get("plaintext"); if (cnContent == null) { cnContent = cnInputs.get("plaintext_hex"); hEncObj.SetContent(hexStringToByteArray(cnContent.AsString())); } else { hEncObj.SetContent(cnContent.AsString()); } SetSendingAttributes(hEncObj, cnEnveloped, true); if (cnEnveloped.ContainsKey("countersign0")) { AddCounterSignature0(hEncObj, cnEnveloped.get("countersign0")); } if (cnEnveloped.ContainsKey("countersign")) { AddCounterSignature(hEncObj, cnEnveloped.get("countersign")); } CBORObject cnRecipients = cnEnveloped.get("recipients"); for (iRecipient = 0; iRecipient 1) && (cSigs.getValues().size() != msg.getCountersignerList().size())) { CFails++; return; } int iCSign; for (iCSign = 0; iCSign < cSigConfig.getValues().size(); iCSign++) { CounterSign sig = msg.getCountersignerList().get(iCSign); OneKey cnKey = BuildKey(cSigConfig.get(iCSign).get("key"), true); SetReceivingAttributes(sig, cSigConfig.get(iCSign)); sig.setKey(cnKey); try { Boolean f = msg.validate(sig); if (!f) CFails++; } catch (Exception e) { CFails++; } } } catch (Exception e) { CFails++; } } void CheckCounterSignatures(Signer msg, CBORObject cSigInfo) { try { CBORObject cSigs = msg.findAttribute(HeaderKeys.CounterSignature); if (cSigs == null) { CFails++; return; } if (cSigs.getType() != CBORType.Array) { CFails++; return; } CBORObject cSigConfig = cSigInfo.get("signers"); if ((cSigConfig.getValues().size() > 1) && (cSigs.getValues().size() != msg.getCountersignerList().size())) { CFails++; return; } int iCSign; for (iCSign = 0; iCSign < cSigConfig.getValues().size(); iCSign++) { CounterSign sig = msg.getCountersignerList().get(iCSign); OneKey cnKey = BuildKey(cSigConfig.get(iCSign).get("key"), true); SetReceivingAttributes(sig, cSigConfig.get(iCSign)); sig.setKey(cnKey); try { Boolean f = msg.validate(sig); if (!f) CFails++; } catch (Exception e) { CFails++; } } } catch (Exception e) { CFails++; } } void CheckCounterSignature0(Message msg, CBORObject cSigInfo) { try { CBORObject cSigs = msg.findAttribute(HeaderKeys.CounterSignature0); if (cSigs == null) { CFails++; return; } if (cSigs.getType() != CBORType.ByteString) { CFails++; return; } CBORObject cSigConfig = cSigInfo.get("signers"); if (1 != cSigConfig.getValues().size()) { CFails++; return; } CounterSign1 sig = msg.getCountersign1(); SetReceivingAttributes(sig, cSigConfig.get(0)); OneKey cnKey = BuildKey(cSigConfig.get(0).get("key"), true); sig.setKey(cnKey); try { Boolean f = msg.validate(sig); if (!f) { throw new Exception("Failed countersignature validation"); } } catch (Exception e) { throw new Exception("Failed countersignature validation"); } } catch (Exception e) { CFails++; } } void CheckCounterSignature0(Signer msg, CBORObject cSigInfo) { try { CBORObject cSigs = msg.findAttribute(HeaderKeys.CounterSignature0); if (cSigs == null) { CFails++; return; } if (cSigs.getType() != CBORType.ByteString) { CFails++; return; } CBORObject cSigConfig = cSigInfo.get("signers"); if (1 != cSigConfig.getValues().size()) { CFails++; return; } CounterSign1 sig = msg.getCountersign1(); SetReceivingAttributes(sig, cSigConfig.get(0)); OneKey cnKey = BuildKey(cSigConfig.get(0).get("key"), true); sig.setKey(cnKey); try { Boolean f = msg.validate(sig); if (!f) { throw new Exception("Failed countersignature validation"); } } catch (Exception e) { throw new Exception("Failed countersignature validation"); } } catch (Exception e) { CFails++; } } }