8
8
9
9
"github.com/notaryproject/notation-go/internal/pkix"
10
10
"github.com/notaryproject/notation-go/internal/slice"
11
+ "github.com/notaryproject/notation-go/internal/trustpolicy"
11
12
"github.com/notaryproject/notation-go/verification/truststore"
12
13
)
13
14
@@ -168,7 +169,7 @@ func (policyDoc *Document) Validate() error {
168
169
policyStatementNameCount [statement .Name ]++
169
170
170
171
// Verify signature verification level is valid
171
- verificationLevel , err := GetVerificationLevel ( statement .SignatureVerification )
172
+ verificationLevel , err := statement .SignatureVerification . GetVerificationLevel ( )
172
173
if err != nil {
173
174
return fmt .Errorf ("trust policy statement %q uses invalid signatureVerification value %q" , statement .Name , statement .SignatureVerification .VerificationLevel )
174
175
}
@@ -213,9 +214,43 @@ func (policyDoc *Document) Validate() error {
213
214
return nil
214
215
}
215
216
217
+ // GetApplicableTrustPolicy returns a pointer to the deep copied TrustPolicy
218
+ // statement that applies to the given registry URI. If no applicable trust
219
+ // policy is found, returns an error
220
+ // see https://github.com/notaryproject/notaryproject/blob/main/trust-store-trust-policy-specification.md#selecting-a-trust-policy-based-on-artifact-uri
221
+ func (trustPolicyDoc * Document ) GetApplicableTrustPolicy (artifactReference string ) (* TrustPolicy , error ) {
222
+
223
+ artifactPath , err := getArtifactPathFromReference (artifactReference )
224
+ if err != nil {
225
+ return nil , err
226
+ }
227
+
228
+ var wildcardPolicy * TrustPolicy
229
+ var applicablePolicy * TrustPolicy
230
+ for _ , policyStatement := range trustPolicyDoc .TrustPolicies {
231
+ if slice .ContainsString (trustpolicy .Wildcard , policyStatement .RegistryScopes ) {
232
+ // we need to deep copy because we can't use the loop variable
233
+ // address. see https://stackoverflow.com/a/45967429
234
+ wildcardPolicy = (& policyStatement ).clone ()
235
+ } else if slice .ContainsString (artifactPath , policyStatement .RegistryScopes ) {
236
+ applicablePolicy = (& policyStatement ).clone ()
237
+ }
238
+ }
239
+
240
+ if applicablePolicy != nil {
241
+ // a policy with exact match for registry URI takes precedence over
242
+ // a wildcard (*) policy.
243
+ return applicablePolicy , nil
244
+ } else if wildcardPolicy != nil {
245
+ return wildcardPolicy , nil
246
+ } else {
247
+ return nil , fmt .Errorf ("artifact %q has no applicable trust policy" , artifactReference )
248
+ }
249
+ }
250
+
216
251
// GetVerificationLevel returns VerificationLevel struct for the given
217
252
// SignatureVerification struct throws error if SignatureVerification is invalid
218
- func GetVerificationLevel (signatureVerification SignatureVerification ) (* VerificationLevel , error ) {
253
+ func (signatureVerification * SignatureVerification ) GetVerificationLevel ( ) (* VerificationLevel , error ) {
219
254
var baseLevel * VerificationLevel
220
255
for _ , l := range VerificationLevels {
221
256
if l .Name == signatureVerification .VerificationLevel {
@@ -281,6 +316,17 @@ func GetVerificationLevel(signatureVerification SignatureVerification) (*Verific
281
316
return customVerificationLevel , nil
282
317
}
283
318
319
+ // clone returns a pointer to the deeply copied TrustPolicy
320
+ func (t * TrustPolicy ) clone () * TrustPolicy {
321
+ return & TrustPolicy {
322
+ Name : t .Name ,
323
+ SignatureVerification : t .SignatureVerification ,
324
+ RegistryScopes : append ([]string (nil ), t .RegistryScopes ... ),
325
+ TrustedIdentities : append ([]string (nil ), t .TrustedIdentities ... ),
326
+ TrustStores : append ([]string (nil ), t .TrustStores ... ),
327
+ }
328
+ }
329
+
284
330
// validateTrustStore validates if the policy statement is following the
285
331
// Notary V2 spec rules for truststores
286
332
func validateTrustStore (statement TrustPolicy ) error {
@@ -300,7 +346,7 @@ func validateTrustedIdentities(statement TrustPolicy) error {
300
346
301
347
// If there is a wildcard in trusted identies, there shouldn't be any other
302
348
//identities
303
- if len (statement .TrustedIdentities ) > 1 && slice .ContainsString (slice .Wildcard , statement .TrustedIdentities ) {
349
+ if len (statement .TrustedIdentities ) > 1 && slice .ContainsString (trustpolicy .Wildcard , statement .TrustedIdentities ) {
304
350
return fmt .Errorf ("trust policy statement %q uses a wildcard trusted identity '*', a wildcard identity cannot be used in conjunction with other values" , statement .Name )
305
351
}
306
352
@@ -311,7 +357,7 @@ func validateTrustedIdentities(statement TrustPolicy) error {
311
357
return fmt .Errorf ("trust policy statement %q has an empty trusted identity" , statement .Name )
312
358
}
313
359
314
- if identity != slice .Wildcard {
360
+ if identity != trustpolicy .Wildcard {
315
361
i := strings .Index (identity , ":" )
316
362
if i < 0 {
317
363
return fmt .Errorf ("trust policy statement %q has trusted identity %q without an identity prefix" , statement .Name , identity )
@@ -321,7 +367,7 @@ func validateTrustedIdentities(statement TrustPolicy) error {
321
367
identityValue := identity [i + 1 :]
322
368
323
369
// notation natively supports x509.subject identities only
324
- if identityPrefix == slice .X509Subject {
370
+ if identityPrefix == trustpolicy .X509Subject {
325
371
dn , err := pkix .ParseDistinguishedName (identityValue )
326
372
if err != nil {
327
373
return err
@@ -332,7 +378,7 @@ func validateTrustedIdentities(statement TrustPolicy) error {
332
378
}
333
379
334
380
// Verify there are no overlapping DNs
335
- if err := hasOverlappingDNs (statement .Name , parsedDNs ); err != nil {
381
+ if err := validateOverlappingDNs (statement .Name , parsedDNs ); err != nil {
336
382
return err
337
383
}
338
384
@@ -350,11 +396,11 @@ func validateRegistryScopes(policyDoc *Document) error {
350
396
if len (statement .RegistryScopes ) == 0 {
351
397
return fmt .Errorf ("trust policy statement %q has zero registry scopes, it must specify registry scopes with at least one value" , statement .Name )
352
398
}
353
- if len (statement .RegistryScopes ) > 1 && slice .ContainsString (slice .Wildcard , statement .RegistryScopes ) {
399
+ if len (statement .RegistryScopes ) > 1 && slice .ContainsString (trustpolicy .Wildcard , statement .RegistryScopes ) {
354
400
return fmt .Errorf ("trust policy statement %q uses wildcard registry scope '*', a wildcard scope cannot be used in conjunction with other scope values" , statement .Name )
355
401
}
356
402
for _ , scope := range statement .RegistryScopes {
357
- if scope != slice .Wildcard {
403
+ if scope != trustpolicy .Wildcard {
358
404
if err := validateRegistryScopeFormat (scope ); err != nil {
359
405
return err
360
406
}
@@ -374,7 +420,7 @@ func validateRegistryScopes(policyDoc *Document) error {
374
420
return nil
375
421
}
376
422
377
- func hasOverlappingDNs (policyName string , parsedDNs []parsedDN ) error {
423
+ func validateOverlappingDNs (policyName string , parsedDNs []parsedDN ) error {
378
424
for i , dn1 := range parsedDNs {
379
425
for j , dn2 := range parsedDNs {
380
426
if i != j && pkix .IsSubsetDN (dn1 .ParsedMap , dn2 .ParsedMap ) {
@@ -397,51 +443,6 @@ func isValidTrustStoreType(s string) bool {
397
443
return false
398
444
}
399
445
400
- // GetApplicableTrustPolicy returns a pointer to the deep copied TrustPolicy
401
- // statement that applies to the given registry URI. If no applicable trust
402
- // policy is found, returns an error
403
- // see https://github.com/notaryproject/notaryproject/blob/main/trust-store-trust-policy-specification.md#selecting-a-trust-policy-based-on-artifact-uri
404
- func GetApplicableTrustPolicy (trustPolicyDoc * Document , artifactReference string ) (* TrustPolicy , error ) {
405
-
406
- artifactPath , err := getArtifactPathFromReference (artifactReference )
407
- if err != nil {
408
- return nil , err
409
- }
410
-
411
- var wildcardPolicy * TrustPolicy
412
- var applicablePolicy * TrustPolicy
413
- for _ , policyStatement := range trustPolicyDoc .TrustPolicies {
414
- if slice .ContainsString (slice .Wildcard , policyStatement .RegistryScopes ) {
415
- // we need to deep copy because we can't use the loop variable
416
- // address. see https://stackoverflow.com/a/45967429
417
- wildcardPolicy = (& policyStatement ).clone ()
418
- } else if slice .ContainsString (artifactPath , policyStatement .RegistryScopes ) {
419
- applicablePolicy = (& policyStatement ).clone ()
420
- }
421
- }
422
-
423
- if applicablePolicy != nil {
424
- // a policy with exact match for registry URI takes precedence over
425
- // a wildcard (*) policy.
426
- return applicablePolicy , nil
427
- } else if wildcardPolicy != nil {
428
- return wildcardPolicy , nil
429
- } else {
430
- return nil , fmt .Errorf ("artifact %q has no applicable trust policy" , artifactReference )
431
- }
432
- }
433
-
434
- // clone returns a pointer to the deeply copied TrustPolicy
435
- func (t * TrustPolicy ) clone () * TrustPolicy {
436
- return & TrustPolicy {
437
- Name : t .Name ,
438
- SignatureVerification : t .SignatureVerification ,
439
- RegistryScopes : append ([]string (nil ), t .RegistryScopes ... ),
440
- TrustedIdentities : append ([]string (nil ), t .TrustedIdentities ... ),
441
- TrustStores : append ([]string (nil ), t .TrustStores ... ),
442
- }
443
- }
444
-
445
446
func getArtifactPathFromReference (artifactReference string ) (string , error ) {
446
447
// TODO support more types of URI like "domain.com/repository",
447
448
// "domain.com/repository:tag"
0 commit comments