func LoadCertsKeys(uname string, upass []byte) (ca []byte, ee []byte, pkey []byte, err error) { user_dir := common.GetConfDir(uname) cafs, err := ioutil.ReadFile(filepath.Join(user_dir, "ca.cert")) if err != nil { return nil, nil, nil, err } ca, err = passcrypto.DecryptMeBase32(string(cafs), upass) if err != nil { return nil, nil, nil, err } ee_pem, err := ioutil.ReadFile(filepath.Join(user_dir, "ee.cert")) if err != nil { return nil, nil, nil, err } ee_blk, _ := pem.Decode(ee_pem) ee = ee_blk.Bytes pkeyfs, err := ioutil.ReadFile(filepath.Join(user_dir, "ee.key")) if err != nil { return nil, nil, nil, err } pkey_pem, _ := pem.Decode(pkeyfs) pkey, err = x509.DecryptPEMBlock(pkey_pem, upass) if err != nil { return nil, nil, nil, err } return }
func LoadManpassCA(uname string, passwd []byte) (*CertKey, error) { //generate a new EE cert/key with specified uname's CA //return encrypted CA cert, EE cert and encrypted EE key in a string confdir := common.GetConfDir(uname) fi, err := os.Stat(confdir) if err != nil { return nil, err } if !fi.IsDir() { return nil, fmt.Errorf("%s is not a directory", confdir) } encacs, err := ioutil.ReadFile(filepath.Join(confdir, "ca.cert")) if err != nil { return nil, err } cacert_der, err := passcrypto.DecryptMeBase32(string(encacs), passwd) if err != nil { return nil, err } encaks, err := ioutil.ReadFile(filepath.Join(confdir, "ca.key")) if err != nil { return nil, err } blk, _ := pem.Decode(encaks) cakey_der, err := x509.DecryptPEMBlock(blk, passwd) var ck CertKey switch blk.Type { case "RSA PRIVATE KEY": ca := new(RSACertKey) cakey, err := x509.ParsePKCS1PrivateKey(cakey_der) if err != nil { return nil, err } ca.key = cakey cert, err := x509.ParseCertificates(cacert_der) if err != nil { return nil, err } ca.cert = *cert[0] ck = ca return &ck, nil case "EC PRIVATE KEY": ecck := new(ECCertKey) priv_key, err := x509.ParseECPrivateKey(cakey_der) if err != nil { return nil, err } ecck.key = priv_key cert, err := x509.ParseCertificates(cacert_der) if err != nil { return nil, err } ecck.cert = *cert[0] ck = ecck return &ck, nil } return nil, errors.New("Unussal error, you shouldn't see this") }
func GenerateCAandEEFiles(username string, passwd []byte) error { //create root CA cert/key and a EE cert/key in the confdir of the username // CA cert are encrypted, CA and EE key are encrypted PEM confdir := common.GetConfDir(username) fi, err := os.Stat(confdir) if err != nil { return err } if !fi.IsDir() { return fmt.Errorf("%s is not a directory", confdir) } ca := new(RSACertKey) err = GenerateROOTCA(ca, username+"-ROOTCA") if err != nil { return err } ee := new(RSACertKey) err = CreateCertWithCA(ca, ee) if err != nil { return err } err = ioutil.WriteFile(filepath.Join(confdir, "ee.cert"), ee.PemCert(), 400) if err != nil { return err } ekeys, err := ee.EncPemKey(passwd) if err != nil { return err } err = ioutil.WriteFile(filepath.Join(confdir, "ee.key"), ekeys, 400) if err != nil { return err } ekeys, err = ca.EncPemKey(passwd) if err != nil { return err } err = ioutil.WriteFile(filepath.Join(confdir, "ca.key"), ekeys, 400) if err != nil { return err } ecerts, err := ca.EncBaseCert(passwd) if err != nil { return err } err = ioutil.WriteFile(filepath.Join(confdir, "ca.cert"), ecerts, 400) if err != nil { return err } return nil }
func InitPassDB(uname string) error { confdir := common.GetConfDir(uname) fi, err := os.Stat(confdir) if err != nil { return err } if !fi.IsDir() { return fmt.Errorf("%s is not a directory", confdir) } dbfname := filepath.Join(confdir, uname+".db") pdb, err := InitDB(dbfname) if err != nil { return err } pdb.InitTable(uname) return nil }
func main() { version_str := "Manpass ver1.0 - server daemon" fmt.Println(version_str) var uname = flag.String("username", "", "specify the username") var svr_port = flag.Int("svrport", 9000, "specify the server listening port") var svr_ip = flag.String("svrip", "127.0.0.1", "specify the server listening IP address") var pipe_pass = flag.Bool("pipepass", false, "enable to use pipe to pass password") var createuser = flag.Bool("create", false, "create a new user") flag.Parse() if *uname == "" || !common.GoodUname(*uname) { fmt.Println("Error: Missing username or invalid username") flag.PrintDefaults() return } confDir := common.GetConfDir(*uname) fi, err := os.Stat(confDir) var upass []byte if (err != nil || !fi.IsDir()) && *createuser { //if user directory doesn't exist if *pipe_pass == false { fmt.Printf("user %s does not exisit! Creating a new user:%s\n", *uname, *uname) upass = common.InputNewPassword(*uname) } else { var pass_str string _, err := fmt.Scan(&pass_str) if err != nil { log.Println(err) log.Fatal("invalid input") } upass = []byte(pass_str) } os.Remove(confDir) fmt.Println("creating needed files...\n") err = os.MkdirAll(confDir, 0700) if err != nil { log.Fatalf("Failed to create directory:%s\n", confDir) } err = pki.GenerateCAandEEFiles(*uname, upass) if err != nil { log.Fatalf("Failed to generate CA and EE cert/keys:%s\n", err) } err = passsql.InitPassDB(*uname) if err != nil { log.Fatalf("Failed to init PassDB:%s\n", err) } fmt.Println("new user created.\n") } else { //load exisiting user directory if *pipe_pass == false { fmt.Printf("Input password for user %s:", *uname) upass, err = terminal.ReadPassword(int(os.Stdin.Fd())) if err != nil { log.Println(err) log.Fatal("invalid input") } } else { var pass_str string _, err := fmt.Scan(&pass_str) if err != nil { log.Println(err) log.Fatal("invalid input") } upass = []byte(pass_str) } } log.Println("Starting server...") dbfile := filepath.Join(confDir, *uname+".db") passdb, err := passsql.LoadDB(dbfile) if err != nil { log.Fatalf("Fatal Error: Failed to load db %s, %s", dbfile, err) } svr, err := api.NewClientAPISVR(*svr_ip, *svr_port, *uname, upass, *passdb, *uname) if err != nil { log.Fatal("Fatal Error: " + string(err.Error())) } err = tlsvr.ListenWithConfig(svr.HttpSvr) if err != nil { log.Fatal("Fatal Error: " + string(err.Error())) } // httpsvr, err := api.NewProvisionSVR(*svr_ip, *svr_port+1, *uname, upass) // httpsvr.Serve() log.Println("Server started.") sigs := make(chan os.Signal, 1) done := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) processSignal(sigs, done, passdb) <-done }