From a0b22bf8e61cf2882c23d1c3b3ca413af7dedf06 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 19 Nov 2018 10:00:23 -0500 Subject: [PATCH 1/2] begin WIP to support W3C Verifiable Claims format --- client/components/proof.js | 5 ++-- package-lock.json | 34 --------------------------- package.json | 3 ++- src/crypto.js | 9 ++++++++ src/proof.js | 47 +++++++++++++++++++++++++------------- 5 files changed, 45 insertions(+), 53 deletions(-) diff --git a/client/components/proof.js b/client/components/proof.js index 6cd3c7c..5cfd487 100644 --- a/client/components/proof.js +++ b/client/components/proof.js @@ -39,7 +39,7 @@ module.exports = class Proof extends Component { return } IpfsID.proof.createProof(username, service, (err, proof) => { - proof.proof = JSON.parse(proof.proof) + // proof.proof = JSON.parse(proof.proof) this.emit('updateProofText', JSON.stringify(proof, null, 2)) }) } @@ -110,13 +110,14 @@ module.exports = class Proof extends Component { class="_proof_tab_ w-90 center pv4 bg-near-white"> ${proofsList.rows.map((item) => { + console.log(item) return html` - + ` })}
${item.doc.proof.message.username}@${item.doc.proof.message.service}${item.doc.url}/ipfs/${item.doc.ipfsContentHash}${item.doc.claim.username}@${item.doc.claim.service}${item.doc.url}/ipfs/${item.doc.ipfsContentHash}
diff --git a/package-lock.json b/package-lock.json index c7da7df..20e040c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7346,27 +7346,6 @@ "latency-monitor": "^0.2.1" } }, - "libp2p-crypto": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/libp2p-crypto/-/libp2p-crypto-0.14.1.tgz", - "integrity": "sha512-JP3bfEzNik76fFIWOeU909+v76tjj5BMukbPCc61bgh1ixftcHkr4bH79duz+oSxRpGA+orCLxvkhgALV+pfwg==", - "requires": { - "asn1.js": "^5.0.1", - "async": "^2.6.1", - "browserify-aes": "^1.2.0", - "bs58": "^4.0.1", - "keypair": "^1.0.1", - "libp2p-crypto-secp256k1": "~0.2.2", - "multihashing-async": "~0.5.1", - "node-forge": "~0.7.6", - "pem-jwk": "^1.5.1", - "protons": "^1.0.1", - "rsa-pem-to-jwk": "^1.1.3", - "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" - } - }, "libp2p-crypto-secp256k1": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/libp2p-crypto-secp256k1/-/libp2p-crypto-secp256k1-0.2.2.tgz", @@ -12712,15 +12691,6 @@ "prepend-http": "^1.0.1" } }, - "ursa-optional": { - "version": "0.9.10", - "resolved": "https://registry.npmjs.org/ursa-optional/-/ursa-optional-0.9.10.tgz", - "integrity": "sha512-RvEbhnxlggX4MXon7KQulTFiJQtLJZpSb9ZSa7ZTkOW0AzqiVTaLjI4vxaSzJBDH9dwZ3ltZadFiBaZslp6haA==", - "requires": { - "bindings": "^1.3.0", - "nan": "^2.11.1" - } - }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -13157,10 +13127,6 @@ } } }, - "webcrypto-shim": { - "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" - }, "webrtcsupport": { "version": "github:ipfs/webrtcsupport#0669f576582c53a3a42aa5ac014fcc5966809615", "from": "webrtcsupport@github:ipfs/webrtcsupport#0669f576582c53a3a42aa5ac014fcc5966809615" diff --git a/package.json b/package.json index a45a912..9783dd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipfs-social-proof", - "version": "0.0.2", + "version": "0.0.3", "description": "IPFS-based Identity & Social Proof", "leadMaintainer": "David Dahl ", "main": "src/index.js", @@ -68,6 +68,7 @@ "pouchdb-upsert": "^2.2.0", "text-encoding": "^0.6.4", "url-parse": "^1.4.3", + "uuid": "^3.3.2", "valid-url": "^1.0.9" }, "contributors": [ diff --git a/src/crypto.js b/src/crypto.js index 1260b37..b74000f 100644 --- a/src/crypto.js +++ b/src/crypto.js @@ -73,6 +73,15 @@ class Crypto { }) } + pemEncodeSignature (signatureBytes) { + return forge.util.binary.base64.encode(signatureBytes) + } + + pemDecodeSignature (pemSignature) { + return forge.util.binary.base64.decode(pemSignature) + } + + get pubKeyDehydrated () { // get a base64 encoded marshaled pub key const pub = this.node._peerInfo.id._privKey.public diff --git a/src/proof.js b/src/proof.js index e5e3fac..71312f0 100644 --- a/src/proof.js +++ b/src/proof.js @@ -1,3 +1,5 @@ +const uuid = require('uuid/v1') + const RemoteProofs = require('./remote-proofs') const {t2a, a2t } = require('./crypto') const { log, error } = require('./log') @@ -65,39 +67,52 @@ class Proof { createProof (username, service, callback, expires=null) { // Sign message, returning an Object with // service, username, message, handle and signature + const SIGNATURE_TYPE = 'RsaSignature2018' + const ISSUER = 'https://github.com/IBM/ipfs-social-proof' const that = this + if (!username || !service) { throw new Error(ERR.ARG_REQ_USERNAME_SERVICE) } const ts = Date.now() - let message = { + let claim = JSON.stringify({ statement: `I am ${username} on ${service}`, // add URL here username: username, service: service - } - - let proof = JSON.stringify({ - message: message, - timestamp: ts, - expires: expires, - ipfsId: this.identity.peerId, - handle: this.identity.handle }) - this.crypto.sign(proof, (err, signature) => { + this.crypto.sign(claim, (err, signature) => { if (err) { throw new Error(err) } - let assertion = { + let proof = { + issuanceDate: new Date().toISOString(), + creator: that.identity.peerId, handle: that.identity.handle, - ipfsId: that.identity.peerId, + // signature: that.crypto.dehydrate(signature), + signatureValue: that.crypto.pemEncodeSignature(signature), + type: SIGNATURE_TYPE, + nonce: uuid(), + } + + if (expires) { + proof.expirationDate = expires + } + + let verifiableCredential = { + '@context': [ + "https://w3.org/2018/credentials/v1" + ], + id: uuid(), // TODO: Should be an url, perhaps an IPFS hash? proof: proof, - signature: that.crypto.dehydrate(signature), - timestamp: ts, - publicKey: that.crypto.pubKeyDehydrated + type: ['VerifiableCredential'], + issuer: ISSUER, + issuanceDate: new Date().toISOString(), + publicKey: that.crypto.pubKeyPem, + claim: JSON.parse(claim), } if (callback) { - callback(err, assertion) + callback(err, verifiableCredential) } }) } From 28d0393f3a923d3fbbf379940bb3501c0e2a3adf Mon Sep 17 00:00:00 2001 From: David Date: Mon, 19 Nov 2018 10:09:03 -0500 Subject: [PATCH 2/2] add some comments/TODOs --- src/proof.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/proof.js b/src/proof.js index 71312f0..76dbce9 100644 --- a/src/proof.js +++ b/src/proof.js @@ -80,6 +80,9 @@ class Proof { statement: `I am ${username} on ${service}`, // add URL here username: username, service: service + // TODO: needs an ID like: "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + // Aparently tied to the url like: "https://example.com/examples/v1" + // Question: can this just be stored in IPFS and references via /ipfs/multihash? }) this.crypto.sign(claim, (err, signature) => {