|
|
@@ -155,6 +155,44 @@ func (s *server) processRequest(data []byte) (interface{}, error) {
|
|
|
return nil, fmt.Errorf("unknown opcode %d", data[0])
|
|
|
}
|
|
|
|
|
|
+func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse bool, extensions []ConstraintExtension, err error) {
|
|
|
+ for len(constraints) != 0 {
|
|
|
+ switch constraints[0] {
|
|
|
+ case agentConstrainLifetime:
|
|
|
+ lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5])
|
|
|
+ constraints = constraints[5:]
|
|
|
+ case agentConstrainConfirm:
|
|
|
+ confirmBeforeUse = true
|
|
|
+ constraints = constraints[1:]
|
|
|
+ case agentConstrainExtension:
|
|
|
+ var msg constrainExtensionAgentMsg
|
|
|
+ if err = ssh.Unmarshal(constraints, &msg); err != nil {
|
|
|
+ return 0, false, nil, err
|
|
|
+ }
|
|
|
+ extensions = append(extensions, ConstraintExtension{
|
|
|
+ ExtensionName: msg.ExtensionName,
|
|
|
+ ExtensionDetails: msg.ExtensionDetails,
|
|
|
+ })
|
|
|
+ constraints = msg.Rest
|
|
|
+ default:
|
|
|
+ return 0, false, nil, fmt.Errorf("unknown constraint type: %d", constraints[0])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func setConstraints(key *AddedKey, constraintBytes []byte) error {
|
|
|
+ lifetimeSecs, confirmBeforeUse, constraintExtensions, err := parseConstraints(constraintBytes)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ key.LifetimeSecs = lifetimeSecs
|
|
|
+ key.ConfirmBeforeUse = confirmBeforeUse
|
|
|
+ key.ConstraintExtensions = constraintExtensions
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func parseRSAKey(req []byte) (*AddedKey, error) {
|
|
|
var k rsaKeyMsg
|
|
|
if err := ssh.Unmarshal(req, &k); err != nil {
|
|
|
@@ -173,7 +211,11 @@ func parseRSAKey(req []byte) (*AddedKey, error) {
|
|
|
}
|
|
|
priv.Precompute()
|
|
|
|
|
|
- return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
|
|
|
+ addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func parseEd25519Key(req []byte) (*AddedKey, error) {
|
|
|
@@ -182,7 +224,12 @@ func parseEd25519Key(req []byte) (*AddedKey, error) {
|
|
|
return nil, err
|
|
|
}
|
|
|
priv := ed25519.PrivateKey(k.Priv)
|
|
|
- return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil
|
|
|
+
|
|
|
+ addedKey := &AddedKey{PrivateKey: &priv, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func parseDSAKey(req []byte) (*AddedKey, error) {
|
|
|
@@ -202,7 +249,11 @@ func parseDSAKey(req []byte) (*AddedKey, error) {
|
|
|
X: k.X,
|
|
|
}
|
|
|
|
|
|
- return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
|
|
|
+ addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (priv *ecdsa.PrivateKey, err error) {
|
|
|
@@ -243,7 +294,12 @@ func parseEd25519Cert(req []byte) (*AddedKey, error) {
|
|
|
if !ok {
|
|
|
return nil, errors.New("agent: bad ED25519 certificate")
|
|
|
}
|
|
|
- return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
|
|
|
+
|
|
|
+ addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func parseECDSAKey(req []byte) (*AddedKey, error) {
|
|
|
@@ -257,7 +313,11 @@ func parseECDSAKey(req []byte) (*AddedKey, error) {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
- return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
|
|
|
+ addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func parseRSACert(req []byte) (*AddedKey, error) {
|
|
|
@@ -300,7 +360,11 @@ func parseRSACert(req []byte) (*AddedKey, error) {
|
|
|
}
|
|
|
priv.Precompute()
|
|
|
|
|
|
- return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
|
|
|
+ addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func parseDSACert(req []byte) (*AddedKey, error) {
|
|
|
@@ -338,7 +402,11 @@ func parseDSACert(req []byte) (*AddedKey, error) {
|
|
|
X: k.X,
|
|
|
}
|
|
|
|
|
|
- return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
|
|
|
+ addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func parseECDSACert(req []byte) (*AddedKey, error) {
|
|
|
@@ -371,7 +439,11 @@ func parseECDSACert(req []byte) (*AddedKey, error) {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
- return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
|
|
|
+ addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
|
|
|
+ if err := setConstraints(addedKey, k.Constraints); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return addedKey, nil
|
|
|
}
|
|
|
|
|
|
func (s *server) insertIdentity(req []byte) error {
|