cluster-bootstrap: make IsValidBootstrapToken() be in constant-time
The function uses BootstrapTokenRegexp.MatchString(token) which is not a recommended practice. Instead, break down the token into its components: ID, secret. The ID is public thus we can use Regexp matching for it. The secret needs constant time comparison. Iterate over every character and make sure it fits the 0-9a-z range and that it has a length of 16.
This commit is contained in:
		| @@ -84,10 +84,36 @@ func TokenFromIDAndSecret(id, secret string) string { | ||||
| 	return fmt.Sprintf("%s.%s", id, secret) | ||||
| } | ||||
|  | ||||
| // IsValidBootstrapToken returns whether the given string is valid as a Bootstrap Token and | ||||
| // in other words satisfies the BootstrapTokenRegexp | ||||
| // IsValidBootstrapToken returns whether the given string is valid as a Bootstrap Token. | ||||
| // Avoid using BootstrapTokenRegexp.MatchString(token) and instead perform constant-time | ||||
| // comparisons on the secret. | ||||
| func IsValidBootstrapToken(token string) bool { | ||||
| 	return BootstrapTokenRegexp.MatchString(token) | ||||
| 	// Must be exactly two strings separated by "." | ||||
| 	t := strings.Split(token, ".") | ||||
| 	if len(t) != 2 { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// Validate the ID: t[0] | ||||
| 	// Using a Regexp for it is safe because the ID is public already | ||||
| 	if !BootstrapTokenIDRegexp.MatchString(t[0]) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	// Validate the secret with constant-time: t[1] | ||||
| 	secret := t[1] | ||||
| 	if len(secret) != api.BootstrapTokenSecretBytes { // Must be an exact size | ||||
| 		return false | ||||
| 	} | ||||
| 	for i := range secret { | ||||
| 		c := int(secret[i]) | ||||
| 		notDigit := (c < 48 || c > 57)   // Character is not in the 0-9 range | ||||
| 		notLetter := (c < 97 || c > 122) // Character is not in the a-z range | ||||
| 		if notDigit && notLetter { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // IsValidBootstrapTokenID returns whether the given string is valid as a Bootstrap Token ID and | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lubomir I. Ivanov
					Lubomir I. Ivanov