github.com/hyperledger/aries-framework-go@v0.3.2/pkg/doc/verifiable/credential_bbs_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 SPDX-License-Identifier: Apache-2.0 4 */ 5 6 package verifiable 7 8 import ( 9 "crypto/sha256" 10 "encoding/base64" 11 "encoding/json" 12 "testing" 13 14 "github.com/stretchr/testify/require" 15 16 "github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub" 17 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld" 18 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite" 19 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignature2020" 20 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignatureproof2020" 21 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/ed25519signature2018" 22 jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json" 23 "github.com/hyperledger/aries-framework-go/pkg/kms" 24 ) 25 26 //nolint:lll 27 func TestCredential_GenerateBBSSelectiveDisclosure(t *testing.T) { 28 s := "uBlesrb_p6VIl-DrJ4Kj7DJ2S45uDqq6cJSgwdw_tVXWazl1XnjQxKsIzrY1RqffBqqT1oFTPi5Nwb_3IGMTWvXeGU7xwZOP8K1jybjknN0ADhp3i8JjTDeuUWH_sixv8ydcx4Qpqq-mMOX7nEm7Dg" 29 _, err := base64.RawURLEncoding.DecodeString(s) 30 require.NoError(t, err) 31 32 vcJSON := ` 33 { 34 "@context": [ 35 "https://www.w3.org/2018/credentials/v1", 36 "https://w3id.org/citizenship/v1", 37 "https://w3id.org/security/bbs/v1" 38 ], 39 "id": "https://issuer.oidp.uscis.gov/credentials/83627465", 40 "type": [ 41 "VerifiableCredential", 42 "PermanentResidentCard" 43 ], 44 "issuer": "did:example:489398593", 45 "identifier": "83627465", 46 "name": "Permanent Resident Card", 47 "description": "Government of Example Permanent Resident Card.", 48 "issuanceDate": "2019-12-03T12:19:52Z", 49 "expirationDate": "2029-12-03T12:19:52Z", 50 "credentialSubject": { 51 "id": "did:example:b34ca6cd37bbf23", 52 "type": [ 53 "PermanentResident", 54 "Person" 55 ], 56 "givenName": "JOHN", 57 "familyName": "SMITH", 58 "gender": "Male", 59 "image": "data:image/png;base64,iVBORw0KGgokJggg==", 60 "residentSince": "2015-01-01", 61 "lprCategory": "C09", 62 "lprNumber": "999-999-999", 63 "commuterClassification": "C1", 64 "birthCountry": "Bahamas", 65 "birthDate": "1958-07-17" 66 } 67 } 68 ` 69 70 pubKey, privKey, err := bbs12381g2pub.GenerateKeyPair(sha256.New, nil) 71 require.NoError(t, err) 72 73 pubKeyBytes, err := pubKey.Marshal() 74 require.NoError(t, err) 75 76 vc, err := parseTestCredential(t, []byte(vcJSON)) 77 require.NoError(t, err) 78 require.Len(t, vc.Proofs, 0) 79 80 signVCWithBBS(t, privKey, pubKeyBytes, vc) 81 signVCWithEd25519(t, vc) 82 83 revealJSON := ` 84 { 85 "@context": [ 86 "https://www.w3.org/2018/credentials/v1", 87 "https://w3id.org/citizenship/v1", 88 "https://w3id.org/security/bbs/v1" 89 ], 90 "type": ["VerifiableCredential", "PermanentResidentCard"], 91 "@explicit": true, 92 "identifier": {}, 93 "issuer": {}, 94 "issuanceDate": {}, 95 "credentialSubject": { 96 "@explicit": true, 97 "type": ["PermanentResident", "Person"], 98 "givenName": {}, 99 "familyName": {}, 100 "gender": {} 101 } 102 } 103 ` 104 105 revealDoc, err := jsonutil.ToMap(revealJSON) 106 require.NoError(t, err) 107 108 nonce := []byte("nonce") 109 110 vcOptions := []CredentialOpt{WithJSONLDDocumentLoader(createTestDocumentLoader(t)), WithPublicKeyFetcher( 111 SingleKey(pubKeyBytes, "Bls12381G2Key2020"))} 112 113 vcWithSelectiveDisclosure, err := vc.GenerateBBSSelectiveDisclosure(revealDoc, nonce, vcOptions...) 114 require.NoError(t, err) 115 require.NotNil(t, vcWithSelectiveDisclosure) 116 require.Len(t, vcWithSelectiveDisclosure.Proofs, 1) 117 118 vcSelectiveDisclosureBytes, err := json.Marshal(vcWithSelectiveDisclosure) 119 require.NoError(t, err) 120 121 sigSuite := bbsblssignatureproof2020.New( 122 suite.WithCompactProof(), 123 suite.WithVerifier(bbsblssignatureproof2020.NewG2PublicKeyVerifier(nonce))) 124 125 vcVerified, err := parseTestCredential(t, vcSelectiveDisclosureBytes, 126 WithEmbeddedSignatureSuites(sigSuite), 127 WithPublicKeyFetcher(SingleKey(pubKeyBytes, "Bls12381G2Key2020")), 128 ) 129 require.NoError(t, err) 130 require.NotNil(t, vcVerified) 131 132 // error cases 133 t.Run("failed generation of selective disclosure", func(t *testing.T) { 134 var ( 135 anotherPubKey *bbs12381g2pub.PublicKey 136 anotherPubKeyBytes []byte 137 ) 138 139 anotherPubKey, _, err = bbs12381g2pub.GenerateKeyPair(sha256.New, nil) 140 require.NoError(t, err) 141 142 anotherPubKeyBytes, err = anotherPubKey.Marshal() 143 require.NoError(t, err) 144 145 vcWithSelectiveDisclosure, err = vc.GenerateBBSSelectiveDisclosure(revealDoc, nonce, 146 WithJSONLDDocumentLoader(createTestDocumentLoader(t)), 147 WithPublicKeyFetcher(SingleKey(anotherPubKeyBytes, "Bls12381G2Key2020"))) 148 require.Error(t, err) 149 require.Contains(t, err.Error(), "create VC selective disclosure") 150 require.Empty(t, vcWithSelectiveDisclosure) 151 }) 152 153 t.Run("public key fetcher is not passed", func(t *testing.T) { 154 vcWithSelectiveDisclosure, err = vc.GenerateBBSSelectiveDisclosure(revealDoc, nonce) 155 require.Error(t, err) 156 require.EqualError(t, err, "public key fetcher is not defined") 157 require.Empty(t, vcWithSelectiveDisclosure) 158 }) 159 160 t.Run("Reveal document with hidden VC mandatory field", func(t *testing.T) { 161 revealJSONWithMissingIssuer := ` 162 { 163 "@context": [ 164 "https://www.w3.org/2018/credentials/v1", 165 "https://w3id.org/citizenship/v1", 166 "https://w3id.org/security/bbs/v1" 167 ], 168 "type": ["VerifiableCredential", "PermanentResidentCard"], 169 "@explicit": true, 170 "identifier": {}, 171 "issuanceDate": {}, 172 "credentialSubject": { 173 "@explicit": true, 174 "type": ["PermanentResident", "Person"], 175 "givenName": {}, 176 "familyName": {}, 177 "gender": {} 178 } 179 } 180 ` 181 182 revealDoc, err = jsonutil.ToMap(revealJSONWithMissingIssuer) 183 require.NoError(t, err) 184 185 vcWithSelectiveDisclosure, err = vc.GenerateBBSSelectiveDisclosure(revealDoc, nonce, vcOptions...) 186 require.Error(t, err) 187 require.Contains(t, err.Error(), "issuer is required") 188 require.Nil(t, vcWithSelectiveDisclosure) 189 }) 190 191 t.Run("VC with no embedded proof", func(t *testing.T) { 192 vc.Proofs = nil 193 vcWithSelectiveDisclosure, err = vc.GenerateBBSSelectiveDisclosure(revealDoc, nonce, vcOptions...) 194 require.Error(t, err) 195 require.EqualError(t, err, "expected at least one proof present") 196 require.Empty(t, vcWithSelectiveDisclosure) 197 }) 198 } 199 200 func signVCWithBBS(t *testing.T, privKey *bbs12381g2pub.PrivateKey, pubKeyBytes []byte, vc *Credential) { 201 t.Helper() 202 203 bbsSigner, err := newBBSSigner(privKey) 204 require.NoError(t, err) 205 206 sigSuite := bbsblssignature2020.New( 207 suite.WithSigner(bbsSigner), 208 suite.WithVerifier(bbsblssignature2020.NewG2PublicKeyVerifier())) 209 210 ldpContext := &LinkedDataProofContext{ 211 SignatureType: "BbsBlsSignature2020", 212 SignatureRepresentation: SignatureProofValue, 213 Suite: sigSuite, 214 VerificationMethod: "did:example:123456#key1", 215 } 216 217 err = vc.AddLinkedDataProof(ldpContext, jsonld.WithDocumentLoader(createTestDocumentLoader(t))) 218 require.NoError(t, err) 219 220 vcSignedBytes, err := json.Marshal(vc) 221 require.NoError(t, err) 222 require.NotEmpty(t, vcSignedBytes) 223 224 vcVerified, err := parseTestCredential(t, vcSignedBytes, 225 WithEmbeddedSignatureSuites(sigSuite), 226 WithPublicKeyFetcher(SingleKey(pubKeyBytes, "Bls12381G2Key2020")), 227 ) 228 require.NoError(t, err) 229 require.NotEmpty(t, vcVerified) 230 } 231 232 func signVCWithEd25519(t *testing.T, vc *Credential) { 233 t.Helper() 234 235 signer, err := newCryptoSigner(kms.ED25519Type) 236 require.NoError(t, err) 237 238 sigSuite := ed25519signature2018.New( 239 suite.WithSigner(signer), 240 suite.WithVerifier(ed25519signature2018.NewPublicKeyVerifier())) 241 242 ldpContext := &LinkedDataProofContext{ 243 SignatureType: "Ed25519Signature2018", 244 SignatureRepresentation: SignatureProofValue, 245 Suite: sigSuite, 246 VerificationMethod: "did:example:123456#key1", 247 } 248 249 err = vc.AddLinkedDataProof(ldpContext, jsonld.WithDocumentLoader(createTestDocumentLoader(t))) 250 require.NoError(t, err) 251 }