Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Support ecdsa #25

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ config/self-description-ignore
config/example.env
output/old
old.json
.idea
3 changes: 2 additions & 1 deletion config/example.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
SIGNATURE_ALGORITHM="PS256"
PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIcFFm9234923kMqkcaj3mfX1xWxKeJb...
...
Expand All @@ -12,4 +13,4 @@ VERIFICATION_METHOD="did:web:delta-dao.com#X509"
X5U_URL="https://delta-dao.com/.well-known/x509CertificateChain.pem"
API_VERSION="2206"
BASE_URL="https://compliance.gaia-x.eu"
CONTROLLER="did:web:delta-dao.com"
CONTROLLER="did:web:delta-dao.com"
109 changes: 82 additions & 27 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,53 +36,109 @@ function sha256(input) {
}

async function sign(hash) {
const algorithm = 'PS256'
const rsaPrivateKey = await jose.importPKCS8(

/*
Key type: Public / Private key pairs (RSA, EC, OKP)
Algorithms:
RSA signature with PKCS #1 and SHA-2: RS256, RS384, RS512
RSA PSS signature with SHA-2: PS256, PS384, PS512
ECDSA signature with SHA-2: ES256, ES256K, ES384, ES512
Edwards-curve DSA: EdDSA
*/
console.log("Signing privateKey")

// JSON Web Key (JWK ). “RSA”, “EC”, “OKP”, and “oct” key types are supported.
const privateKey = await jose.importPKCS8(
process.env.PRIVATE_KEY,
algorithm
process.env.SIGNATURE_ALGORITHM
)

try {
const jws = await new jose.CompactSign(new TextEncoder().encode(hash))
.setProtectedHeader({ alg: 'PS256', b64: false, crit: ['b64'] })
.sign(rsaPrivateKey)
if (process.env.SIGNATURE_ALGORITHM === "PS256") {
console.log("Using PS256")
try {
// This supports RSA keys only
const jws = await new jose.CompactSign(new TextEncoder().encode(hash))
.setProtectedHeader({alg: 'PS256', b64: false, crit: ['b64']})
.sign(privateKey)
console.log("Finished signing")
return jws
} catch (error) {
console.log(error)
}

return jws
} catch (error) {
console.error(error)
}
else if (process.env.SIGNATURE_ALGORITHM === "ES256") {
console.log("Using ES256")
try {
const jws = await new jose.SignJWT({ 'urn:example:claim': true })
.setProtectedHeader({ alg: 'ES256' })
.sign(privateKey)
console.log("Finished signing")
return jws
} catch (error) {
console.log(error)
}
}
else {
message = "Unsupported SIGNATURE_ALGORITHM" + process.env.SIGNATURE_ALGORITHM + ". Exiting!"
console.log(message)
throw new Error(message)
}
}

async function createProof(hash) {
console.log("Creating proof")
const proof = {
type: 'JsonWebSignature2020',
created: new Date(CURRENT_TIME).toISOString(),
proofPurpose: 'assertionMethod',
verificationMethod:
process.env.VERIFICATION_METHOD ?? 'did:web:compliance.lab.gaia-x.eu',
jws: await sign(hash),
jws: await sign(hash)
}

console.log("Finished proof")
return proof
}

async function verify(jws) {
const algorithm = 'PS256'
async function verify(jwt) {
const algorithm = process.env.SIGNATURE_ALGORITHM
const x509 = await jose.importX509(process.env.CERTIFICATE, algorithm)
const publicKeyJwk = await jose.exportJWK(x509)
const pubkey = await jose.importJWK(publicKeyJwk, process.env.SIGNATURE_ALGORITHM)

if (process.env.SIGNATURE_ALGORITHM === "PS256") {
jws = jwt.jws.replace('..', `.${hash}.`)
console.log("Using PS256")
try {
const result = await jose.compactVerify(jws, pubkey)
return {
protectedHeader: result.protectedHeader,
content: new TextDecoder().decode(result.payload),
}
} catch (error) {
console.error("PS256 verification failed: " + error)
}

const pubkey = await jose.importJWK(publicKeyJwk, 'PS256')

try {
const result = await jose.compactVerify(jws, pubkey)

return {
protectedHeader: result.protectedHeader,
content: new TextDecoder().decode(result.payload),
}
else if (process.env.SIGNATURE_ALGORITHM === "ES256") {
console.log("Using ES256")
console.log(jwt)
try {

const { payload, protectedHeader } = await jose.jwtVerify(jwt.jws, pubkey)

console.log(payload)
console.log(protectedHeader)
return {
protectedHeader: protectedHeader,
payload: payload,
content: payload
}
} catch (error) {
console.error("ES256 verification failed: " + error)
}
} catch (error) {
return {}
}
return {}
}

async function createSignedSdFile(selfDescription, proof) {
Expand Down Expand Up @@ -177,9 +233,8 @@ async function main() {
: '❌ SD signing failed (local)'
)

const verificationResult = await verify(
proof.jws.replace('..', `.${hash}.`)
)
const verificationResult = await verify(proof)
console.log(verificationResult)
logger(
verificationResult?.content === hash
? '✅ Verification successful (local)'
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
"dependencies": {
"axios": "^0.27.2",
"dotenv": "^16.0.1",
"jose": "^4.8.1"
"jose": "^4.10.3"
}
}