func TestSaveForeverCertAllowed(t *testing.T) { allConfig := SetupSignerdConfig(1, 0) environment := "testing" envConfig := allConfig[environment] requestHandler := makeCertRequestHandler(allConfig) pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(foreverUserCertString)) if err != nil { t.Fatalf("Parsing canned cert failed: %v", err) } cert := pubKey.(*ssh.Certificate) err = requestHandler.saveSigningRequest(envConfig, environment, "reason: testing", "DEADBEEFDEADBEEF", 1, cert) if err != nil { t.Fatalf("Should have worked, failed with: %v", err) } pubKey, _, _, _, err = ssh.ParseAuthorizedKey([]byte(twentyTwentyFiveCertString)) if err != nil { t.Fatalf("Parsing canned cert failed: %v", err) } cert = pubKey.(*ssh.Certificate) err = requestHandler.saveSigningRequest(envConfig, environment, "reason: testing", "DEADBEEFDEADBEEF2", 1, cert) if err != nil { t.Fatalf("Should have worked, failed with: %v", err) } }
func getTwoBoringCerts(t *testing.T) (*ssh.Certificate, *ssh.Certificate) { pubKeyOne, _, _, _, err := ssh.ParseAuthorizedKey([]byte(boringUserCertString)) if err != nil { t.Fatalf("Parsing canned cert failed: %v", err) } boringCertOne := pubKeyOne.(*ssh.Certificate) pubKeyTwo, _, _, _, err := ssh.ParseAuthorizedKey([]byte(boringUserCertString)) if err != nil { t.Fatalf("Parsing canned cert failed: %v", err) } boringCertTwo := pubKeyTwo.(*ssh.Certificate) return boringCertOne, boringCertTwo }
func findKeyLocally(key ssh.PublicKey) (string, error) { sshDir := os.Getenv("HOME") + "/.ssh" dirEntries, err := ioutil.ReadDir(sshDir) if err != nil { return "", fmt.Errorf("Could not read your .ssh directory %s: %s\n", sshDir, err) } for idx := range dirEntries { entry := dirEntries[idx] if strings.HasSuffix(entry.Name(), ".pub") { pubKeyPath := sshDir + "/" + entry.Name() pubBuf, err := ioutil.ReadFile(pubKeyPath) if err != nil { fmt.Printf("Trouble reading public key %s: %s\n", pubKeyPath, err) continue } pubKey, _, _, _, err := ssh.ParseAuthorizedKey(pubBuf) if err != nil { fmt.Printf("Trouble parsing public key %s (might be unsupported format): %s\n", pubKeyPath, err) continue } if bytes.Equal(pubKey.Marshal(), key.Marshal()) { return pubKeyPath, nil } } } return "", fmt.Errorf("Couldn't find ssh key for cert.\n") }
// RunKeyImport imports a key from a file func RunKeyImport(ns string, out io.Writer) error { client := doit.DoitConfig.GetGodoClient() keyPath := doit.DoitConfig.GetString(ns, doit.ArgKeyPublicKeyFile) keyName := doit.DoitConfig.GetString(ns, doit.ArgKeyName) keyFile, err := ioutil.ReadFile(keyPath) if err != nil { return err } _, comment, _, _, err := ssh.ParseAuthorizedKey(keyFile) if err != nil { return err } if len(keyName) < 1 { keyName = comment } kcr := &godo.KeyCreateRequest{ Name: keyName, PublicKey: string(keyFile), } r, _, err := client.Keys.Create(kcr) if err != nil { return err } return doit.DisplayOutput(r, out) }
func (ctrl *Controller) authorizeKey(conn ssh.ConnMetadata, key ssh.PublicKey) ( *ssh.Permissions, error) { marshaledKey := key.Marshal() for _, authorizedKey := range ctrl.authorizedKeys { if bytes.Compare(authorizedKey.Marshal(), marshaledKey) == 0 { return &ssh.Permissions{}, nil } } nodes, err := ctrl.cluster.GetDir("console/authorized_keys") if err != nil { if err == cluster.ErrNotFound { return nil, fmt.Errorf("unauthorized") } return nil, err } for path, value := range nodes { key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(value)) if err != nil { fmt.Printf("bad authorized key from etcd: %s: %s\n", path, err) } if bytes.Compare(key.Marshal(), marshaledKey) == 0 { return &ssh.Permissions{}, nil } } return nil, fmt.Errorf("unauthorized") }
func (d *SDeployKeys) ParsePublicKey(b []byte) (ssh.PublicKey, error) { s, _, _, _, err := ssh.ParseAuthorizedKey(b) if err != nil { return nil, errors.New("Invalid RSA public key format") } return s, nil }
func TestAgentForward(t *testing.T) { server := newServer(t) defer server.Shutdown() conn := server.Dial(clientConfig()) defer conn.Close() keyring := agent.NewKeyring() keyring.Add(testPrivateKeys["dsa"], nil, "") pub := testPublicKeys["dsa"] sess, err := conn.NewSession() if err != nil { t.Fatalf("NewSession: %v", err) } if err := agent.RequestAgentForwarding(sess); err != nil { t.Fatalf("RequestAgentForwarding: %v", err) } if err := agent.ForwardToAgent(conn, keyring); err != nil { t.Fatalf("SetupForwardKeyring: %v", err) } out, err := sess.CombinedOutput("ssh-add -L") if err != nil { t.Fatalf("running ssh-add: %v, out %s", err, out) } key, _, _, _, err := ssh.ParseAuthorizedKey(out) if err != nil { t.Fatalf("ParseAuthorizedKey(%q): %v", out, err) } if !bytes.Equal(key.Marshal(), pub.Marshal()) { t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub)) } }
// Converts a public key to authorized keys format. func PublicKeyToAuthorizedKeysFormat(in string) (string, error) { s := strings.Replace(strings.Replace(strings.TrimSpace(in), "\r\n", "\n", -1), "\r", "\n", -1) lines := strings.Split(s, "\n") if len(lines) == 1 { publicKey, comment, _, _, err := ssh.ParseAuthorizedKey([]byte(lines[0])) if err != nil { return "", fmt.Errorf("failed to parse public key from authorized keys format: %v", err) } encodedKey := base64.StdEncoding.EncodeToString(publicKey.Marshal()) return fmt.Sprintf("%s %s %s", publicKey.Type(), encodedKey, comment), nil } else { var encodedKey string continuationLine := false for _, line := range lines { if continuationLine || strings.ContainsAny(line, ":-") { continuationLine = strings.HasSuffix(line, "\\") } else { encodedKey += line } } rawKey, err := base64.StdEncoding.DecodeString(encodedKey) fmt.Println(encodedKey) if err != nil { return "", fmt.Errorf("detected SSH2 format, but contains invalid base64 content: %v", err) } fmt.Println(string(base64.StdEncoding.EncodeToString(rawKey))) publicKey, err := ssh.ParsePublicKey(rawKey) if err != nil { return "", fmt.Errorf("failed to parse public key from SSH2 format: %v", err) } newEncodedKey := base64.StdEncoding.EncodeToString(publicKey.Marshal()) return fmt.Sprintf("%s %s cloug@cloug", publicKey.Type(), newEncodedKey), nil } }
func getPubKeyForUser(username string) (ssh.PublicKey, error) { cwd, err := os.Getwd() if err != nil { log.Printf("(getPubKeyForUser) >> Error: Could not figure out current working directory: %s", err.Error()) return nil, err } pubKeyPath := fmt.Sprintf("%s/data/%s/id_rsa.pub", cwd, username) pubKeyFile, err := os.Open(pubKeyPath) if err != nil { log.Printf("(getPubKeyForUser) >> Error opening pub key file '%s' for user '%s': %s", pubKeyPath, username, err.Error()) return nil, fmt.Errorf("(getPubKeyForUser) >> Error opening pub key file '%s'", pubKeyPath) } defer pubKeyFile.Close() var authorizedPubKeyBuf []byte authorizedPubKeyBuf, err = ioutil.ReadAll(pubKeyFile) if err != nil { log.Printf("(getPubKeyForUser) >> Error: Could not read PubKey at path: %s", pubKeyPath) return nil, err } authorizedPubKey, _, _, _, err = ssh.ParseAuthorizedKey(authorizedPubKeyBuf) if err != nil { log.Printf("(getPubKeyForUser) >> Error: Unable to parse AuthorizedPubKey: '%s'. Error: %s", pubKeyPath, err.Error()) return nil, err } log.Printf("(getPubKeyForUser) >> Successfully parsed authorized PubKey: %s\n", pubKeyPath) return authorizedPubKey, nil }
func parseAuthFile(filename string) ([]*sshmux.User, error) { var users []*sshmux.User authFile, err := ioutil.ReadFile(filename) if err != nil { return nil, err } // Parse authfile as authorized_key for len(authFile) > 0 { var ( pk ssh.PublicKey comment string ) pk, comment, _, authFile, err = ssh.ParseAuthorizedKey(authFile) if err != nil { return nil, err } u := &sshmux.User{ PublicKey: pk, Name: comment, } users = append(users, u) } return users, nil }
func TestRejectRequestAfterSigning(t *testing.T) { allConfig := SetupSignerdConfig(2, 0) environment := "testing" envConfig := allConfig[environment] requestHandler := makeCertRequestHandler(allConfig) pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(boringUserCertString)) if err != nil { t.Fatalf("Parsing canned cert failed: %v", err) } cert := pubKey.(*ssh.Certificate) err = requestHandler.saveSigningRequest(envConfig, environment, "reason: testing", "DEADBEEFDEADBEEF", 1, cert) if err != nil { t.Fatalf("Should have succeeded. Failed with: %v", err) } err = requestHandler.addConfirmation("DEADBEEFDEADBEEF", "23:10:8d:d0:54:90:d5:d1:2e:4d:05:fe:4b:54:29:e4", envConfig, false) if err != nil { t.Fatalf("Sign should have worked. It failed: %v", err) } err = requestHandler.rejectRequest("DEADBEEFDEADBEEF", "23:10:8d:d0:54:90:d5:d1:2e:4d:05:fe:4b:54:29:e4", envConfig) if err != nil { t.Fatalf("Should have succeeded. Failed with: %v", err) } err = requestHandler.addConfirmation("DEADBEEFDEADBEEF", "23:10:8d:d0:54:90:d5:d1:2e:4d:05:fe:4b:54:29:e4", envConfig, false) if err == nil { t.Fatalf("Sign after reject should fail.") } }
func TestCompareCertsPublicKey(t *testing.T) { boringCertOne, boringCertTwo := getTwoBoringCerts(t) boringCertTwo.Key, _, _, _, _ = ssh.ParseAuthorizedKey([]byte(signerPublicKeyString)) if compareCerts(boringCertOne, boringCertTwo) { t.Fatalf("Certs should not have been equal.") } }
func (s *GandalfServer) addKeys(w http.ResponseWriter, r *http.Request) { userName := r.URL.Query().Get(":name") var keys map[string]string defer r.Body.Close() err := json.NewDecoder(r.Body).Decode(&keys) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } s.usersLock.Lock() defer s.usersLock.Unlock() userKeys, ok := s.keys[userName] if !ok { http.Error(w, user.ErrUserNotFound.Error(), http.StatusNotFound) return } for name, body := range keys { if _, _, _, _, err := ssh.ParseAuthorizedKey([]byte(body)); err != nil { http.Error(w, user.ErrInvalidKey.Error(), http.StatusBadRequest) return } for _, userKey := range userKeys { if name == userKey.Name { http.Error(w, user.ErrDuplicateKey.Error(), http.StatusConflict) return } } } for name, body := range keys { userKeys = append(userKeys, key{Name: name, Body: body}) } s.keys[userName] = userKeys }
func TestCanCreateHostFingerPrint(t *testing.T) { var key = []byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEbKq5U57fhzQ3SBbs3NVmgY2ouYZfPhc6cXBNEFpRT3T100fnbkYw+EHi76nwsp+uGxk08kh4GG881DrgotptrJj2dJxXpWp/SFdVu5S9fFU6l6dCTC9IBYYCCV8PvXbBZ3oDZyyyJT7/vXSaUdbk3x9MeNlYrgItm2KY6MdHYEg8R994Sspn1sE4Ydey5DfG/WNWVrzFCI0sWI3yj4zuCcUXFz9sEG8fIYikD9rNuohiMenWjkj6oLTwZGVW2q4wRL0051XBkmfnPD/H6gqOML9MbZQ8D6/+az0yF9oD61SkifhBNBRRNaIab/Np7XD61siR8zNMG/vCKjFGICnp andrew@localhost") publicKey, _, _, _, _ := ssh.ParseAuthorizedKey(key) in, out := sshTunnel.formatHostFingerprint(publicKey), "65:30:38:96:35:56:4f:64:64:e8:e3:a4:7d:59:3e:19" if in != out { t.Errorf("sshTunnel.formatHostFingerprint(key) = %v, want %v", in, out) } }
// toPublicKey parses a public key and returns an *rsa.PublicKey. // credit to stackoverflow http://stackoverflow.com/q/31593329 func toPublicKey(key string) (*rsa.PublicKey, error) { raw := []byte(key) pub, _, _, _, err := ssh.ParseAuthorizedKey(raw) if err != nil { return nil, err } return reflect.ValueOf(pub). Convert(reflect.TypeOf(new(rsa.PublicKey))).Interface().(*rsa.PublicKey), nil }
// ParseAuthorisedKey parses a non-comment line from an // authorized_keys file and returns the constituent parts. // Based on description in "man sshd". func ParseAuthorisedKey(line string) (*AuthorisedKey, error) { key, comment, _, _, err := ssh.ParseAuthorizedKey([]byte(line)) if err != nil { return nil, fmt.Errorf("invalid authorized_key %q", line) } return &AuthorisedKey{ Type: key.Type(), Key: key.Marshal(), Comment: comment, }, nil }
//export c_ParseAuthorizedKey func c_ParseAuthorizedKey(in []byte) (uint64, *C.char, *C.char, *C.char, int, int, *C.char) { pkey, comment, options, rest, err := ssh.ParseAuthorizedKey(in) if err != nil { return IH, nil, nil, nil, 0, ErrorCodeInternal, C.CString(err.Error()) } pkey_handle := RegisterObject(&pkey) mopt := strings.Join(options, "\xff") return uint64(pkey_handle), C.CString(comment), C.CString(mopt), C.CString(string(rest)), len(rest), ErrorCodeSuccess, nil }
func (opts *getConfigOpts) RunE(_ *cobra.Command, args []string) error { if len(args) > 0 { return errorWantedNoArgs } var marshal func(interface{}) ([]byte, error) switch opts.output { case "yaml": marshal = yaml.Marshal case "json": marshal = func(v interface{}) ([]byte, error) { return json.MarshalIndent(v, "", " ") } default: return errors.New("unknown output format " + opts.output) } config, err := opts.API.GetConfig(noInstanceID) if err != nil { return err } if opts.fingerprint != "" && config.Git.Key != "" { pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(config.Git.Key)) if err != nil { config.Git.Key = "unable to parse public key" } else { switch opts.fingerprint { case "md5": hash := md5.Sum(pk.Marshal()) fingerprint := "" for i, b := range hash { fingerprint = fmt.Sprintf("%s%0.2x", fingerprint, b) if i < len(hash)-1 { fingerprint = fingerprint + ":" } } config.Git.Key = fingerprint case "sha256": hash := sha256.Sum256(pk.Marshal()) config.Git.Key = strings.TrimRight(base64.StdEncoding.EncodeToString(hash[:]), "=") } } } // Since we always want to output whatever we got, use UnsafeInstanceConfig bytes, err := marshal(flux.UnsafeInstanceConfig(config)) if err != nil { return errors.Wrap(err, "marshalling to output format "+opts.output) } os.Stdout.Write(bytes) return nil }
// loadPrivateKey loads an parses a PEM encoded private key file. func loadPublicKey(path string) ssh.PublicKey { bs, err := ioutil.ReadFile(path) if err != nil { log.Fatal("error open public key file: ", err) } rsa, _, _, _, err2 := ssh.ParseAuthorizedKey(bs) if err2 != nil { log.Fatal("error cannot parse public key file: ", err2) } return rsa }
func (s *SSHKey) parse() error { var err error s.Pubkey, s.Comment, s.Options, s.Rest, err = ssh.ParseAuthorizedKey(s.Key) if err != nil { return err } s.Type = s.Pubkey.Type() // FIXME: compute bits // FIXME: check min/max key length return nil }
func loadPubKey(file string, path string) (string, error) { filePath := filepath.Join(path, file) sshKeyBytes, err := ioutil.ReadFile(filePath) if err != nil { return "", err } k, _, _, _, err := ssh.ParseAuthorizedKey(sshKeyBytes) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(k.Marshal()), nil }
// Helper function to get the fingerprint of a SSH public key func PublicKeyFingerprint(pubkey string) (string, string) { byteString := []byte(pubkey) pk, comment, _, _, err := ssh.ParseAuthorizedKey(byteString) if err != nil { return "", "" } hash := md5.Sum(pk.Marshal()) fingerprint := Rfc4716Hex(hash[:]) return fingerprint, comment }
func acceptPublicKey(keystr string) func(ssh.ConnMetadata, ssh.PublicKey) (*ssh.Permissions, error) { goodkey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(keystr)) if err != nil { panic(fmt.Errorf("error parsing key: %s", err)) } return func(_ ssh.ConnMetadata, inkey ssh.PublicKey) (*ssh.Permissions, error) { if bytes.Compare(inkey.Marshal(), goodkey.Marshal()) == 0 { return nil, nil } return nil, fmt.Errorf("public key rejected") } }
// SSHGetFingerprint returns the fingerprint of an SSH key func SSHGetFingerprint(key []byte) (string, error) { publicKey, comment, _, _, err := ssh.ParseAuthorizedKey(key) if err != nil { return "", err } switch reflect.TypeOf(publicKey).String() { case "*ssh.rsaPublicKey", "*ssh.dsaPublicKey", "*ssh.ecdsaPublicKey": md5sum := md5.Sum(publicKey.Marshal()) return publicKey.Type() + " " + rfc4716hex(md5sum[:]) + " " + comment, nil default: return "", errors.New("Can't handle this key") } }
func TestAuthorizedKeyShouldParse(t *testing.T) { testSubject, err := NewOpenSshKeyPairWithSize(512) if err != nil { t.Fatalf("Failed to create a new OpenSSH key pair, err=%s.", err) } authorizedKey := testSubject.AuthorizedKey() _, _, _, _, err = ssh.ParseAuthorizedKey([]byte(authorizedKey)) if err != nil { t.Fatalf("Failed to parse the authorized key, err=%s", err) } }
func (c *SSHCluster) findSSHKeySigners() (signers []privateKeySigner) { keyDir := filepath.Join(c.sshDir()) if stat, err := os.Stat(keyDir); err != nil || !stat.IsDir() { return } walkFunc := func(path string, info os.FileInfo, err error) error { if info.IsDir() { return nil } if strings.HasSuffix(path, ".pub") { return nil } data, err := ioutil.ReadFile(path) if err != nil { return nil } b, _ := pem.Decode(data) if b == nil { return nil } s := privateKeySigner{ base: c.base, path: path, pem: b, Encrypted: x509.IsEncryptedPEMBlock(b), } if s.Encrypted { publicKeyPath := fmt.Sprintf("%s.pub", path) if stat, err := os.Stat(publicKeyPath); err == nil && !stat.IsDir() { if data, err := ioutil.ReadFile(publicKeyPath); err == nil { pk, _, _, _, err := ssh.ParseAuthorizedKey(data) if err == nil { s.publicKey = pk } } } signers = append(signers, s) return nil } privateKey, err := x509.ParsePKCS1PrivateKey(b.Bytes) if err != nil { return nil } s.key = privateKey signers = append(signers, s) return nil } filepath.Walk(keyDir, walkFunc) sort.Sort(decryptedFirst(signers)) return }
func handleSSHKeyAppend(args map[string]interface{}) error { var ( token = args["<token>"].(string) truncate = args["-r"].(bool) sshKeysDir = args["-k"].(string) ) sshKeyPath := filepath.Join(sshKeysDir, token) sshKeyDir := filepath.Dir(sshKeyPath) if _, err := os.Stat(sshKeyDir); os.IsNotExist(err) { err = os.MkdirAll(sshKeyDir, 0700) if err != nil { return err } } openFlags := os.O_CREATE | os.O_WRONLY if truncate { openFlags |= os.O_TRUNC } else { openFlags |= os.O_APPEND } sshKeyBytes, err := ioutil.ReadAll(os.Stdin) if err != nil { return err } _, comment, _, _, err := ssh.ParseAuthorizedKey(sshKeyBytes) if err != nil { return fmt.Errorf("can't parse key: %s", err) } keyFile, err := os.OpenFile(sshKeyPath, openFlags, 0644) if err != nil { return err } defer keyFile.Close() _, err = keyFile.Write(sshKeyBytes) if err != nil { return err } fmt.Println("Added new key with comment:", comment) return nil }
func (a *authDB) Add(c *configClient) { // Parse SSH key k, _, _, _, err := ssh.ParseAuthorizedKey([]byte(c.Protocols.SCP.PublicKey)) if err != nil { log.Fatalf("Failed to parse ssh public key for %s: %s", c.Hostname, err) } c.Protocols.SCP.parsedPublicKey = &k // Add to map a.clients[c.Hostname] = c for _, addr := range c.AdditionalAddresses { a.clients[addr] = c } }
func newUserKey(pubKeyFile string) (*userKey, error) { userKey := new(userKey) if len(pubKeyFile) > 0 { pubKeyBytes, err := ioutil.ReadFile(pubKeyFile) if err != nil { return nil, errors.New("Failed to read public key") } userKey.PublicKey, _, _, _, err = ssh.ParseAuthorizedKey(pubKeyBytes) if err != nil { return nil, errors.New("Failed to parse authorized key") } return userKey, nil } key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, errors.New("Failed to generate key pair") } userKey.PublicKey, err = ssh.NewPublicKey(key.Public()) if err != nil { return nil, errors.New("Failed to extract public key from generated key pair") } // To support Ansible calling back to us we need to write // this file down privateKeyDer := x509.MarshalPKCS1PrivateKey(key) privateKeyBlock := pem.Block{ Type: "RSA PRIVATE KEY", Headers: nil, Bytes: privateKeyDer, } tf, err := ioutil.TempFile("", "ansible-key") if err != nil { return nil, errors.New("failed to create temp file for generated key") } _, err = tf.Write(pem.EncodeToMemory(&privateKeyBlock)) if err != nil { return nil, errors.New("failed to write private key to temp file") } err = tf.Close() if err != nil { return nil, errors.New("failed to close private key temp file") } userKey.privKeyFile = tf.Name() return userKey, nil }
func newKey(name, user, raw string) (*Key, error) { key, comment, _, _, err := ssh.ParseAuthorizedKey([]byte(raw)) if err != nil { return nil, ErrInvalidKey } body := ssh.MarshalAuthorizedKey(key.(ssh.PublicKey)) k := Key{ Name: name, Body: string(body), Comment: comment, UserName: user, CreatedAt: time.Now(), } return &k, nil }