diff --git a/doc/did/doc.go b/doc/did/doc.go index a1dbabf..9c625be 100644 --- a/doc/did/doc.go +++ b/doc/did/doc.go @@ -48,13 +48,17 @@ const ( jsonldController = "controller" jsonldOwner = "owner" - jsonldCreator = "creator" - jsonldCreated = "created" - jsonldProofValue = "proofValue" - jsonldSignatureValue = "signatureValue" - jsonldDomain = "domain" - jsonldNonce = "nonce" - jsonldProofPurpose = "proofPurpose" + jsonldCreator = "creator" + jsonldCreated = "created" + jsonldProofValue = "proofValue" + jsonldSignatureValue = "signatureValue" + jsonldDomain = "domain" + jsonldNonce = "nonce" + jsonldProofPurpose = "proofPurpose" + jsonldChallenge = "challenge" + jsonldCryptoSuite = "cryptosuite" + jsonldVerificationMethod = "verificationMethod" + jsonldJWS = "jws" // various public key encodings. jsonldPublicKeyBase58 = "publicKeyBase58" @@ -487,14 +491,18 @@ func (r *rawDoc) UnmarshalJSON(data []byte) error { // Proof is cryptographic proof of the integrity of the DID Document. type Proof struct { - Type string - Created *time.Time - Creator string - ProofValue []byte - Domain string - Nonce []byte - ProofPurpose string - relativeURL bool + Type string + Created *time.Time + Creator string + ProofValue []byte + Domain string + Nonce []byte + ProofPurpose string + CryptoSuite string + Challenge string + VerificationMethod string + JWS string + relativeURL bool } // UnmarshalJSON unmarshals a DID Document. @@ -659,13 +667,17 @@ func populateProofs(context, didID, baseURI string, rawProofs []interface{}) ([] } proof := Proof{ - Type: stringEntry(emap[jsonldType]), - Creator: creator, - ProofValue: proofValue, - ProofPurpose: stringEntry(emap[jsonldProofPurpose]), - Domain: stringEntry(emap[jsonldDomain]), - Nonce: nonce, - relativeURL: isRelative, + Type: stringEntry(emap[jsonldType]), + Creator: creator, + ProofValue: proofValue, + ProofPurpose: stringEntry(emap[jsonldProofPurpose]), + Domain: stringEntry(emap[jsonldDomain]), + VerificationMethod: stringEntry(emap[jsonldVerificationMethod]), + CryptoSuite: stringEntry(emap[jsonldCryptoSuite]), + Challenge: stringEntry(emap[jsonldChallenge]), + JWS: stringEntry(emap[jsonldJWS]), + Nonce: nonce, + relativeURL: isRelative, } created := stringEntry(emap[jsonldCreated]) @@ -1246,7 +1258,8 @@ func (doc *Doc) MarshalJSON() ([]byte, error) { } // VerifyProof verifies document proofs. -func (doc *Doc) VerifyProof(suites []api.VerifierSuite, jsonldOpts ...processor.Opts) error { +// Deprecated. Please use vc-go/verifiable.VerifyDIDProof(). +func (doc *Doc) VerifyProof(suites []api.VerifierSuite, opts ...processor.Opts) error { if len(doc.Proof) == 0 { return ErrProofNotFound } @@ -1261,7 +1274,7 @@ func (doc *Doc) VerifyProof(suites []api.VerifierSuite, jsonldOpts ...processor. return fmt.Errorf("create verifier: %w", err) } - return v.Verify(docBytes, jsonldOpts...) + return v.Verify(docBytes, opts...) } // VerificationMethods returns verification methods of DID Doc of certain relationship. @@ -1552,10 +1565,10 @@ func populateRawVerification(context, baseURI, didID string, verifications []Ver func populateRawProofs(context, didID, baseURI string, proofs []Proof) []interface{} { rawProofs := make([]interface{}, 0, len(proofs)) - k := jsonldProofValue + proofValueKey := jsonldProofValue if context == contextV011 { - k = jsonldSignatureValue + proofValueKey = jsonldSignatureValue } for _, p := range proofs { @@ -1564,15 +1577,36 @@ func populateRawProofs(context, didID, baseURI string, proofs []Proof) []interfa creator = makeRelativeDIDURL(p.Creator, baseURI, didID) } - rawProofs = append(rawProofs, map[string]interface{}{ + rawProof := map[string]interface{}{ jsonldType: p.Type, jsonldCreated: p.Created, jsonldCreator: creator, - k: sigproof.EncodeProofValue(p.ProofValue, p.Type), jsonldDomain: p.Domain, jsonldNonce: base64.RawURLEncoding.EncodeToString(p.Nonce), jsonldProofPurpose: p.ProofPurpose, - }) + } + + if len(p.ProofValue) > 0 { + rawProof[proofValueKey] = sigproof.EncodeProofValue(p.ProofValue, p.Type) + } + + if p.JWS != "" { + rawProof[jsonldJWS] = p.JWS + } + + if p.CryptoSuite != "" { + rawProof[jsonldCryptoSuite] = p.CryptoSuite + } + + if p.Challenge != "" { + rawProof[jsonldChallenge] = p.Challenge + } + + if p.VerificationMethod != "" { + rawProof[jsonldVerificationMethod] = p.VerificationMethod + } + + rawProofs = append(rawProofs, rawProof) } return rawProofs diff --git a/doc/did/doc_test.go b/doc/did/doc_test.go index 026d3b1..d252d07 100644 --- a/doc/did/doc_test.go +++ b/doc/did/doc_test.go @@ -476,12 +476,18 @@ func TestValidWithProof(t *testing.T) { require.NoError(t, err) eProof := Proof{ - Type: "Ed25519Signature2018", - Created: &created, - Creator: "did:method:abc#key-1", - ProofValue: proofValue, - Domain: "", - Nonce: nonce, + Type: "Ed25519Signature2018", + Created: &created, + Creator: "did:method:abc#key-1", + ProofValue: proofValue, + Domain: "", + Nonce: nonce, + ProofPurpose: "assertionMethod", + CryptoSuite: "cryptosuite1", + Challenge: "challenge1", + VerificationMethod: "verificationMethod1", + JWS: "jws1", + relativeURL: false, } require.Equal(t, []Proof{eProof}, doc.Proof) @@ -1153,19 +1159,6 @@ func TestValidateDidDocProof(t *testing.T) { } }) - t.Run("test did doc proof without proofValue", func(t *testing.T) { - raw := &rawDoc{} - require.NoError(t, json.Unmarshal([]byte(validDocWithProof), &raw)) - proof, ok := raw.Proof[0].(map[string]interface{}) - require.True(t, ok) - delete(proof, jsonldProofValue) - bytes, err := json.Marshal(raw) - require.NoError(t, err) - err = validate(bytes, raw.schemaLoader()) - require.Error(t, err) - require.Contains(t, err.Error(), "proofValue is required") - }) - t.Run("test did doc proof without proofValue v0.11", func(t *testing.T) { raw := &rawDoc{} require.NoError(t, json.Unmarshal([]byte(validDocV011WithProof), &raw)) @@ -1234,7 +1227,7 @@ func TestRequiresLegacyHandling(t *testing.T) { func TestJSONConversion(t *testing.T) { docs := []string{ - validDoc, validDocV011, validDocWithProofAndJWK, docV011WithVerificationRelationships, validDocWithBase, + validDoc, validDocV011, validDocWithProofAndJWK, docV011WithVerificationRelationships, validDocWithBase, validDocWithProof, } for _, d := range docs { // setup -> create Document from json byte data @@ -2019,7 +2012,12 @@ const validDocWithProof = `{ "domain": "", "nonce": "", "proofValue": "6mdES87erjP5r1qCSRW__otj-A_Rj0YgRO7XU_0Amhwdfa7AAmtGUSFGflR_fZqPYrY9ceLRVQCJ49s0q7-LBA", - "type": "Ed25519Signature2018" + "type": "Ed25519Signature2018", + "proofPurpose": "assertionMethod", + "challenge": "challenge1", + "cryptosuite": "cryptosuite1", + "verificationMethod": "verificationMethod1", + "jws": "jws1" }], "verificationMethod": [{ "controller": "did:method:abc", @@ -2074,7 +2072,12 @@ const validDocV011WithProof = `{ "domain": "", "nonce": "", "signatureValue": "6mdES87erjP5r1qCSRW__otj-A_Rj0YgRO7XU_0Amhwdfa7AAmtGUSFGflR_fZqPYrY9ceLRVQCJ49s0q7-LBA", - "type": "Ed25519Signature2018" + "type": "Ed25519Signature2018", + "proofPurpose": "assertionMethod", + "challenge": "challenge1", + "cryptosuite": "cryptosuite1", + "verificationMethod": "verificationMethod1", + "jws": "jws1" }], "publicKey": [{ "owner": "did:method:abc", diff --git a/doc/did/schema.go b/doc/did/schema.go index 745e68a..7706621 100644 --- a/doc/did/schema.go +++ b/doc/did/schema.go @@ -106,7 +106,7 @@ const ( "definitions": { "proof": { "type": "object", - "required": [ "type", "proofValue"], + "required": [ "type"], "properties": { "type": { "type": "string", @@ -122,6 +122,9 @@ const ( "proofValue": { "type": "string" }, + "jws": { + "type": "string" + }, "domain": { "type": "string" }, diff --git a/doc/ld/proof/proof.go b/doc/ld/proof/proof.go index 7001069..69ab3dd 100644 --- a/doc/ld/proof/proof.go +++ b/doc/ld/proof/proof.go @@ -9,7 +9,6 @@ import ( "encoding/base64" "errors" "fmt" - "strings" "github.com/multiformats/go-multibase" @@ -41,6 +40,7 @@ const ( jsonldCapabilityChain = "capabilityChain" ed25519Signature2020 = "Ed25519Signature2020" + dataIntegrityProof = "DataIntegrityProof" ) // Proof is cryptographic proof of the integrity of the DID Document. @@ -150,23 +150,21 @@ func decodeBase64(s string) ([]byte, error) { // DecodeProofValue decodes proofValue basing on proof type. func DecodeProofValue(s, proofType string) ([]byte, error) { - if proofType == ed25519Signature2020 { + switch proofType { + case ed25519Signature2020: _, value, err := multibase.Decode(s) if err == nil { return value, nil } return nil, errors.New("unsupported encoding") + case dataIntegrityProof: + // No need to decode Data integrity proof as encoding/decoding logic for this proof type + // is managed by vc-go/dataintegrity package. + return []byte(s), nil + default: + return decodeBase64(s) } - - if strings.HasPrefix(s, "z") { // maybe base58 - _, value, err := multibase.Decode(s) - if err == nil { - return value, nil - } - } - - return decodeBase64(s) } // stringEntry. @@ -232,9 +230,14 @@ func (p *Proof) JSONLdObject() map[string]interface{} { // nolint:gocyclo // EncodeProofValue decodes proofValue basing on proof type. func EncodeProofValue(proofValue []byte, proofType string) string { - if proofType == ed25519Signature2020 { + switch proofType { + case ed25519Signature2020: encoded, _ := multibase.Encode(multibase.Base58BTC, proofValue) //nolint: errcheck return encoded + case dataIntegrityProof: + // No need to encode Data integrity proof as encoding/decoding logic for this proof type + // is managed by vc-go/dataintegrity package. + return string(proofValue) } return base64.RawURLEncoding.EncodeToString(proofValue) diff --git a/doc/signature/signer/signer.go b/doc/signature/signer/signer.go index b78687c..70055b5 100644 --- a/doc/signature/signer/signer.go +++ b/doc/signature/signer/signer.go @@ -36,6 +36,7 @@ func New(signatureSuites ...SignatureSuite) *DocumentSigner { } // Sign will sign JSON LD document. +// Deprecated. Please use vc-go/verifiable.AddDIDLinkedDataProof(). func (signer *DocumentSigner) Sign( context *Context, jsonLdDoc []byte, diff --git a/doc/signature/verifier/verifier.go b/doc/signature/verifier/verifier.go index c5f0e7a..5ecfcc2 100644 --- a/doc/signature/verifier/verifier.go +++ b/doc/signature/verifier/verifier.go @@ -40,6 +40,7 @@ func New(resolver keyResolver, suites ...api.VerifierSuite) (*DocumentVerifier, } // Verify will verify document proofs. +// Deprecated. Please use vc-go/verifiable.VerifyDIDProof(). func (dv *DocumentVerifier) Verify(jsonLdDoc []byte, opts ...processor.Opts) error { var jsonLdObject map[string]interface{} @@ -52,6 +53,7 @@ func (dv *DocumentVerifier) Verify(jsonLdDoc []byte, opts ...processor.Opts) err } // VerifyObject will verify document proofs for JSON LD object. +// Deprecated. Please use vc-go/verifiable.VerifyDIDProof(). func (dv *DocumentVerifier) VerifyObject(jsonLdObject map[string]interface{}, opts ...processor.Opts) error { proofs, err := proof.GetProofs(jsonLdObject) if err != nil {