make the ECDSA JSON signature parsing more robust

also rename the format to "Raw JSON"
as I will later introduce "JSON Web Signature"
This commit is contained in:
CPlusSharp 2024-04-14 12:42:44 +02:00
parent 7b54d9e873
commit 1fbc7e03f0
4 changed files with 70 additions and 19 deletions

View File

@ -48,7 +48,7 @@ class ECDSASign extends Operation {
value: [ value: [
"ASN.1 HEX", "ASN.1 HEX",
"P1363 HEX", "P1363 HEX",
"JSON" "Raw JSON"
] ]
} }
]; ];
@ -86,7 +86,7 @@ class ECDSASign extends Operation {
case "P1363 HEX": case "P1363 HEX":
result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex); result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex);
break; break;
case "JSON": { case "Raw JSON": {
const signatureRS = r.KJUR.crypto.ECDSA.parseSigHexInHexRS(signatureASN1Hex); const signatureRS = r.KJUR.crypto.ECDSA.parseSigHexInHexRS(signatureASN1Hex);
result = JSON.stringify(signatureRS); result = JSON.stringify(signatureRS);
break; break;

View File

@ -5,6 +5,7 @@
*/ */
import Operation from "../Operation.mjs"; import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import r from "jsrsasign"; import r from "jsrsasign";
/** /**
@ -32,7 +33,7 @@ class ECDSASignatureConversion extends Operation {
"Auto", "Auto",
"ASN.1 HEX", "ASN.1 HEX",
"P1363 HEX", "P1363 HEX",
"JSON" "Raw JSON"
] ]
}, },
{ {
@ -41,7 +42,7 @@ class ECDSASignatureConversion extends Operation {
value: [ value: [
"ASN.1 HEX", "ASN.1 HEX",
"P1363 HEX", "P1363 HEX",
"JSON" "Raw JSON"
] ]
} }
]; ];
@ -57,11 +58,19 @@ class ECDSASignatureConversion extends Operation {
const outputFormat = args[1]; const outputFormat = args[1];
// detect input format // detect input format
let inputJson;
if (inputFormat === "Auto") { if (inputFormat === "Auto") {
if (input.substr(0, 2) === "30" && r.ASN1HEX.isASN1HEX(input)) { try {
inputJson = JSON.parse(input);
if (typeof(inputJson) === "object") {
inputFormat = "Raw JSON";
}
} catch {}
}
if (inputFormat === "Auto") {
if (input.substring(0, 2) === "30" && r.ASN1HEX.isASN1HEX(input)) {
inputFormat = "ASN.1 HEX"; inputFormat = "ASN.1 HEX";
} else if (input.indexOf("{") !== -1) {
inputFormat = "JSON";
} else { } else {
inputFormat = "P1363 HEX"; inputFormat = "P1363 HEX";
} }
@ -76,8 +85,14 @@ class ECDSASignatureConversion extends Operation {
case "P1363 HEX": case "P1363 HEX":
signatureASN1Hex = r.KJUR.crypto.ECDSA.concatSigToASN1Sig(input); signatureASN1Hex = r.KJUR.crypto.ECDSA.concatSigToASN1Sig(input);
break; break;
case "JSON": { case "Raw JSON": {
const inputJson = JSON.parse(input); if (!inputJson) inputJson = JSON.parse(input);
if (!inputJson.r) {
throw new OperationError('No "r" value in the signature JSON');
}
if (!inputJson.s) {
throw new OperationError('No "s" value in the signature JSON');
}
signatureASN1Hex = r.KJUR.crypto.ECDSA.hexRSSigToASN1Sig(inputJson.r, inputJson.s); signatureASN1Hex = r.KJUR.crypto.ECDSA.hexRSSigToASN1Sig(inputJson.r, inputJson.s);
break; break;
} }
@ -92,7 +107,7 @@ class ECDSASignatureConversion extends Operation {
case "P1363 HEX": case "P1363 HEX":
result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex); result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex);
break; break;
case "JSON": { case "Raw JSON": {
const signatureRS = r.KJUR.crypto.ECDSA.parseSigHexInHexRS(signatureASN1Hex); const signatureRS = r.KJUR.crypto.ECDSA.parseSigHexInHexRS(signatureASN1Hex);
result = JSON.stringify(signatureRS); result = JSON.stringify(signatureRS);
break; break;

View File

@ -33,7 +33,7 @@ class ECDSAVerify extends Operation {
"Auto", "Auto",
"ASN.1 HEX", "ASN.1 HEX",
"P1363 HEX", "P1363 HEX",
"JSON" "Raw JSON"
] ]
}, },
{ {
@ -74,11 +74,19 @@ class ECDSAVerify extends Operation {
} }
// detect input format // detect input format
let inputJson;
if (inputFormat === "Auto") { if (inputFormat === "Auto") {
if (input.substr(0, 2) === "30" && r.ASN1HEX.isASN1HEX(input)) { try {
inputJson = JSON.parse(input);
if (typeof(inputJson) === "object") {
inputFormat = "Raw JSON";
}
} catch {}
}
if (inputFormat === "Auto") {
if (input.substring(0, 2) === "30" && r.ASN1HEX.isASN1HEX(input)) {
inputFormat = "ASN.1 HEX"; inputFormat = "ASN.1 HEX";
} else if (input.indexOf("{") !== -1) {
inputFormat = "JSON";
} else { } else {
inputFormat = "P1363 HEX"; inputFormat = "P1363 HEX";
} }
@ -93,8 +101,14 @@ class ECDSAVerify extends Operation {
case "P1363 HEX": case "P1363 HEX":
signatureASN1Hex = r.KJUR.crypto.ECDSA.concatSigToASN1Sig(input); signatureASN1Hex = r.KJUR.crypto.ECDSA.concatSigToASN1Sig(input);
break; break;
case "JSON": { case "Raw JSON": {
const inputJson = JSON.parse(input); if (!inputJson) inputJson = JSON.parse(input);
if (!inputJson.r) {
throw new OperationError('No "r" value in the signature JSON');
}
if (!inputJson.s) {
throw new OperationError('No "s" value in the signature JSON');
}
signatureASN1Hex = r.KJUR.crypto.ECDSA.hexRSSigToASN1Sig(inputJson.r, inputJson.s); signatureASN1Hex = r.KJUR.crypto.ECDSA.hexRSSigToASN1Sig(inputJson.r, inputJson.s);
break; break;
} }

View File

@ -271,6 +271,28 @@ TestRegister.addTests([
} }
] ]
}, },
{
name: "ECDSA Verify: JSON signature missing r",
input: JSON.stringify({s: JSON.parse(P256.signature.sha256.json).s}),
expectedOutput: 'No "r" value in the signature JSON',
recipeConfig: [
{
"op": "ECDSA Verify",
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
}
]
},
{
name: "ECDSA Verify: JSON signature missing s",
input: JSON.stringify({r: JSON.parse(P256.signature.sha256.json).r}),
expectedOutput: 'No "s" value in the signature JSON',
recipeConfig: [
{
"op": "ECDSA Verify",
"args": ["Auto", "SHA-256", P256.publicKey, ASCII_TEXT]
}
]
},
{ {
name: "ECDSA Verify: Using private key fails", name: "ECDSA Verify: Using private key fails",
input: P256.signature.sha256.asn1, input: P256.signature.sha256.asn1,
@ -324,7 +346,7 @@ TestRegister.addTests([
recipeConfig: [ recipeConfig: [
{ {
"op": "ECDSA Signature Conversion", "op": "ECDSA Signature Conversion",
"args": ["Auto", "JSON"] "args": ["Auto", "Raw JSON"]
} }
] ]
}, },
@ -357,7 +379,7 @@ TestRegister.addTests([
recipeConfig: [ recipeConfig: [
{ {
"op": "ECDSA Signature Conversion", "op": "ECDSA Signature Conversion",
"args": ["Auto", "JSON"] "args": ["Auto", "Raw JSON"]
} }
] ]
}, },
@ -390,7 +412,7 @@ TestRegister.addTests([
recipeConfig: [ recipeConfig: [
{ {
"op": "ECDSA Signature Conversion", "op": "ECDSA Signature Conversion",
"args": ["Auto", "JSON"] "args": ["Auto", "Raw JSON"]
} }
] ]
} }