func (h *certRequestHandler) saveSigningRequest(config ssh_ca_util.SignerdConfig, environment, reason, requestIDStr string, requestSerial uint64, cert *ssh.Certificate) (bool, error) { requesterFp := ssh_ca_util.MakeFingerprint(cert.SignatureKey.Marshal()) maxValidBefore := uint64(time.Now().Add(time.Duration(config.MaxCertLifetime) * time.Second).Unix()) if config.MaxCertLifetime != 0 && cert.ValidBefore > maxValidBefore { return false, fmt.Errorf("Certificate is valid longer than maximum permitted by configuration %d > %d", cert.ValidBefore, maxValidBefore) } // We override keyid here so that its a server controlled value. Instead of // letting a requester attempt to spoof it. var ok bool cert.KeyId, ok = config.AuthorizedUsers[requesterFp] if !ok { return false, fmt.Errorf("Requester fingerprint (%s) not found in config", requesterFp) } if requestSerial == 0 { return false, fmt.Errorf("Serial number not set.") } cert.Serial = requestSerial certRequest := newcertRequest() certRequest.request = cert if environment == "" { return false, fmt.Errorf("Environment is a required field") } certRequest.environment = environment if reason == "" { return false, fmt.Errorf("Reason is a required field") } certRequest.reason = reason if len(requestIDStr) < 12 { return false, fmt.Errorf("Request id is too short to be useful.") } _, ok = h.state[requestIDStr] if ok { return false, fmt.Errorf("Request id '%s' already in use.", requestIDStr) } h.state[requestIDStr] = certRequest // This is the special case of supporting auto-signing. if config.NumberSignersRequired < 0 { signed, err := h.maybeSignWithCa(requestIDStr, config.NumberSignersRequired, config.SigningKeyFingerprint) if signed && err == nil { return true, nil } } return false, nil }
func (h *certRequestHandler) saveSigningRequest(config ssh_ca_util.SignerdConfig, environment, reason, requestIDStr string, requestSerial uint64, cert *ssh.Certificate) error { requesterFp := ssh_ca_util.MakeFingerprint(cert.SignatureKey.Marshal()) // We override keyid here so that its a server controlled value. Instead of // letting a requester attempt to spoof it. var ok bool cert.KeyId, ok = config.AuthorizedUsers[requesterFp] if !ok { return fmt.Errorf("Requester fingerprint (%s) not found in config", requesterFp) } if requestSerial == 0 { return fmt.Errorf("Serial number not set.") } cert.Serial = requestSerial certRequest := newcertRequest() certRequest.request = cert if environment == "" { return fmt.Errorf("Environment is a required field") } certRequest.environment = environment if reason == "" { return fmt.Errorf("Reason is a required field") } certRequest.reason = reason if len(requestIDStr) < 12 { return fmt.Errorf("Request id is too short to be useful.") } _, ok = h.state[requestIDStr] if ok { return fmt.Errorf("Request id '%s' already in use.", requestIDStr) } h.state[requestIDStr] = certRequest return nil }
func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string, constraints []byte) error { var req []byte switch k := s.(type) { case *rsa.PrivateKey: if len(k.Primes) != 2 { return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes)) } k.Precompute() req = ssh.Marshal(rsaCertMsg{ Type: cert.Type(), CertBytes: cert.Marshal(), D: k.D, Iqmp: k.Precomputed.Qinv, P: k.Primes[0], Q: k.Primes[1], Comments: comment, Constraints: constraints, }) case *dsa.PrivateKey: req = ssh.Marshal(dsaCertMsg{ Type: cert.Type(), CertBytes: cert.Marshal(), X: k.X, Comments: comment, Constraints: constraints, }) case *ecdsa.PrivateKey: req = ssh.Marshal(ecdsaCertMsg{ Type: cert.Type(), CertBytes: cert.Marshal(), D: k.D, Comments: comment, Constraints: constraints, }) case *ed25519.PrivateKey: req = ssh.Marshal(ed25519CertMsg{ Type: cert.Type(), CertBytes: cert.Marshal(), Pub: []byte(*k)[32:], Priv: []byte(*k), Comments: comment, Constraints: constraints, }) default: return fmt.Errorf("agent: unsupported key type %T", s) } // if constraints are present then the message type needs to be changed. if len(constraints) != 0 { req[0] = agentAddIdConstrained } signer, err := ssh.NewSignerFromKey(s) if err != nil { return err } if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 { return errors.New("agent: signer and cert have different public key") } resp, err := c.call(req) if err != nil { return err } if _, ok := resp.(*successAgentMsg); ok { return nil } return errors.New("agent: failure") }
func MakeCertificate() ssh.Certificate { var newCert ssh.Certificate // The sign() method fills in Nonce for us newCert.Nonce = make([]byte, 32) return newCert }