xref: /aosp_15_r20/external/tink/go/keyset/validation.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang// Copyright 2018 Google LLC
2*e7b1675dSTing-Kang Chang//
3*e7b1675dSTing-Kang Chang// Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang// you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang// You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang//
7*e7b1675dSTing-Kang Chang//      http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang//
9*e7b1675dSTing-Kang Chang// Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang// distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang// See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang// limitations under the License.
14*e7b1675dSTing-Kang Chang//
15*e7b1675dSTing-Kang Chang////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Changpackage keyset
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Changimport (
20*e7b1675dSTing-Kang Chang	"fmt"
21*e7b1675dSTing-Kang Chang
22*e7b1675dSTing-Kang Chang	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
23*e7b1675dSTing-Kang Chang)
24*e7b1675dSTing-Kang Chang
25*e7b1675dSTing-Kang Chang// ValidateKeyVersion checks whether the given version is valid. The version is valid
26*e7b1675dSTing-Kang Chang// only if it is the range [0..maxExpected]
27*e7b1675dSTing-Kang Changfunc ValidateKeyVersion(version, maxExpected uint32) error {
28*e7b1675dSTing-Kang Chang	if version > maxExpected {
29*e7b1675dSTing-Kang Chang		return fmt.Errorf("key has version %v; only keys with version in range [0..%v] are supported",
30*e7b1675dSTing-Kang Chang			version, maxExpected)
31*e7b1675dSTing-Kang Chang	}
32*e7b1675dSTing-Kang Chang	return nil
33*e7b1675dSTing-Kang Chang}
34*e7b1675dSTing-Kang Chang
35*e7b1675dSTing-Kang Chang// Validate validates the given key set.
36*e7b1675dSTing-Kang Chang// Returns nil if it is valid; an error otherwise.
37*e7b1675dSTing-Kang Changfunc Validate(keyset *tinkpb.Keyset) error {
38*e7b1675dSTing-Kang Chang	if keyset == nil {
39*e7b1675dSTing-Kang Chang		return fmt.Errorf("Validate() called with nil")
40*e7b1675dSTing-Kang Chang	}
41*e7b1675dSTing-Kang Chang	if len(keyset.Key) == 0 {
42*e7b1675dSTing-Kang Chang		return fmt.Errorf("empty keyset")
43*e7b1675dSTing-Kang Chang	}
44*e7b1675dSTing-Kang Chang	primaryKeyID := keyset.PrimaryKeyId
45*e7b1675dSTing-Kang Chang	hasPrimaryKey := false
46*e7b1675dSTing-Kang Chang	numEnabledKeys := 0
47*e7b1675dSTing-Kang Chang	for _, key := range keyset.Key {
48*e7b1675dSTing-Kang Chang		if err := validateKey(key); err != nil {
49*e7b1675dSTing-Kang Chang			return err
50*e7b1675dSTing-Kang Chang		}
51*e7b1675dSTing-Kang Chang		if key.Status != tinkpb.KeyStatusType_ENABLED {
52*e7b1675dSTing-Kang Chang			continue
53*e7b1675dSTing-Kang Chang		}
54*e7b1675dSTing-Kang Chang		if key.KeyId == primaryKeyID {
55*e7b1675dSTing-Kang Chang			if hasPrimaryKey {
56*e7b1675dSTing-Kang Chang				return fmt.Errorf("keyset contains multiple primary keys")
57*e7b1675dSTing-Kang Chang			}
58*e7b1675dSTing-Kang Chang			hasPrimaryKey = true
59*e7b1675dSTing-Kang Chang		}
60*e7b1675dSTing-Kang Chang		numEnabledKeys++
61*e7b1675dSTing-Kang Chang	}
62*e7b1675dSTing-Kang Chang	if numEnabledKeys == 0 {
63*e7b1675dSTing-Kang Chang		return fmt.Errorf("keyset must contain at least one ENABLED key")
64*e7b1675dSTing-Kang Chang	}
65*e7b1675dSTing-Kang Chang
66*e7b1675dSTing-Kang Chang	if !hasPrimaryKey {
67*e7b1675dSTing-Kang Chang		return fmt.Errorf("keyset does not contain a valid primary key")
68*e7b1675dSTing-Kang Chang	}
69*e7b1675dSTing-Kang Chang	return nil
70*e7b1675dSTing-Kang Chang}
71*e7b1675dSTing-Kang Chang
72*e7b1675dSTing-Kang Chang/*
73*e7b1675dSTing-Kang ChangvalidateKey validates the given key.
74*e7b1675dSTing-Kang ChangReturns nil if it is valid; an error otherwise.
75*e7b1675dSTing-Kang Chang*/
76*e7b1675dSTing-Kang Changfunc validateKey(key *tinkpb.Keyset_Key) error {
77*e7b1675dSTing-Kang Chang	if key == nil {
78*e7b1675dSTing-Kang Chang		return fmt.Errorf("ValidateKey() called with nil")
79*e7b1675dSTing-Kang Chang	}
80*e7b1675dSTing-Kang Chang	if key.KeyData == nil {
81*e7b1675dSTing-Kang Chang		return fmt.Errorf("key %d has no key data", key.KeyId)
82*e7b1675dSTing-Kang Chang	}
83*e7b1675dSTing-Kang Chang	if key.OutputPrefixType != tinkpb.OutputPrefixType_TINK &&
84*e7b1675dSTing-Kang Chang		key.OutputPrefixType != tinkpb.OutputPrefixType_LEGACY &&
85*e7b1675dSTing-Kang Chang		key.OutputPrefixType != tinkpb.OutputPrefixType_RAW &&
86*e7b1675dSTing-Kang Chang		key.OutputPrefixType != tinkpb.OutputPrefixType_CRUNCHY {
87*e7b1675dSTing-Kang Chang		return fmt.Errorf("key %d has unknown prefix", key.KeyId)
88*e7b1675dSTing-Kang Chang	}
89*e7b1675dSTing-Kang Chang	if key.Status != tinkpb.KeyStatusType_ENABLED &&
90*e7b1675dSTing-Kang Chang		key.Status != tinkpb.KeyStatusType_DISABLED &&
91*e7b1675dSTing-Kang Chang		key.Status != tinkpb.KeyStatusType_DESTROYED {
92*e7b1675dSTing-Kang Chang		return fmt.Errorf("key %d has unknown status", key.KeyId)
93*e7b1675dSTing-Kang Chang	}
94*e7b1675dSTing-Kang Chang	return nil
95*e7b1675dSTing-Kang Chang}
96