mirror of https://github.com/docker/docs.git
				
				
				
			Pad the ECDSA key that gets put into the Yubikey so it has 32 bytes.
Apparently that is required by the template, and will error if it does not. Sometimes, ECDSA keys are generated which when encoded seems to only have 31 bytes. Signed-off-by: Ying Li <ying.li@docker.com> Signed-off-by: David Lawrence <david.lawrence@docker.com> Signed-off-by: Ying Li <ying.li@docker.com> (github: endophage)
This commit is contained in:
		
							parent
							
								
									91b7d87a7b
								
							
						
					
					
						commit
						397adb4291
					
				|  | @ -30,6 +30,9 @@ const ( | |||
| 	KeymodeTouch     = 1 // touch enabled
 | ||||
| 	KeymodePinOnce   = 2 // require pin entry once
 | ||||
| 	KeymodePinAlways = 4 // require pin entry all the time
 | ||||
| 
 | ||||
| 	// the key size, when importing a key into yubikey, MUST be 32 bytes
 | ||||
| 	ecdsaPrivateKeySize = 32 | ||||
| ) | ||||
| 
 | ||||
| // what key mode to use when generating keys
 | ||||
|  | @ -136,6 +139,18 @@ func (y *YubiPrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts | |||
| 	return sig, nil | ||||
| } | ||||
| 
 | ||||
| // If a byte array is less than the number of bytes specified by
 | ||||
| // ecdsaPrivateKeySize, left-zero-pad the byte array until
 | ||||
| // it is the required size.
 | ||||
| func ensurePrivateKeySize(payload []byte) []byte { | ||||
| 	final := payload | ||||
| 	if len(payload) < ecdsaPrivateKeySize { | ||||
| 		final = make([]byte, ecdsaPrivateKeySize) | ||||
| 		copy(final[ecdsaPrivateKeySize-len(payload):], payload) | ||||
| 	} | ||||
| 	return final | ||||
| } | ||||
| 
 | ||||
| // addECDSAKey adds a key to the yubikey
 | ||||
| func addECDSAKey( | ||||
| 	ctx *pkcs11.Ctx, | ||||
|  | @ -161,7 +176,7 @@ func addECDSAKey( | |||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	ecdsaPrivKeyD := ecdsaPrivKey.D.Bytes() | ||||
| 	ecdsaPrivKeyD := ensurePrivateKeySize(ecdsaPrivKey.D.Bytes()) | ||||
| 	logrus.Debugf("Getting D bytes: %v\n", ecdsaPrivKeyD) | ||||
| 
 | ||||
| 	template, err := NewCertificate(role) | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ package trustmanager | |||
| 
 | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/docker/notary/passphrase" | ||||
|  | @ -25,6 +26,32 @@ func clearAllKeys(t *testing.T) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestEnsurePrivateKeySizePassesThroughRightSizeArrays(t *testing.T) { | ||||
| 	fullByteArray := make([]byte, ecdsaPrivateKeySize) | ||||
| 	for i := range fullByteArray { | ||||
| 		fullByteArray[i] = byte(1) | ||||
| 	} | ||||
| 
 | ||||
| 	result := ensurePrivateKeySize(fullByteArray) | ||||
| 	assert.True(t, reflect.DeepEqual(fullByteArray, result)) | ||||
| } | ||||
| 
 | ||||
| // The pad32Byte helper function left zero-pads byte arrays that are less than
 | ||||
| // ecdsaPrivateKeySize bytes
 | ||||
| func TestEnsurePrivateKeySizePadsLessThanRequiredSizeArrays(t *testing.T) { | ||||
| 	shortByteArray := make([]byte, ecdsaPrivateKeySize/2) | ||||
| 	for i := range shortByteArray { | ||||
| 		shortByteArray[i] = byte(1) | ||||
| 	} | ||||
| 
 | ||||
| 	expected := append( | ||||
| 		make([]byte, ecdsaPrivateKeySize-ecdsaPrivateKeySize/2), | ||||
| 		shortByteArray...) | ||||
| 
 | ||||
| 	result := ensurePrivateKeySize(shortByteArray) | ||||
| 	assert.True(t, reflect.DeepEqual(expected, result)) | ||||
| } | ||||
| 
 | ||||
| func testAddKey(t *testing.T, store *YubiKeyStore) (data.PrivateKey, error) { | ||||
| 	privKey, err := GenerateECDSAKey(rand.Reader) | ||||
| 	assert.NoError(t, err) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue