func processGetRequest(reqData *messages.RequestData, req *messages.Request, role string) ([]byte, error) { tx, err := db.Begin() if err != nil { log.Printf("initiating database transaction failed (%v)", err) return messages.NewServerResponse(false, "Failed to retrieve secret.", nil) } sec, err := db.RetrieveSecret(tx, reqData.Ident, req.Public) if err != nil { log.Printf("retrieving secret %s failed (%v)", reqData.Ident, err) db.Finalise(tx, err) return messages.NewServerResponse(false, "Failed to retrieve secret.", nil) } db.Finalise(tx, nil) msg := crypto.RecoverSecret(sec) if msg == nil { return messages.NewServerResponse(false, "Failed to retrieve secret.", nil) } var response = struct { Secret []byte `json:"secret"` }{msg} out, err := json.Marshal(response) if err != nil { return messages.NewServerResponse(false, "Failed to retrieve secret.", nil) } return messages.NewServerResponse(true, "Secret retrieved.", out) }
func processProvision(reqData *messages.RequestData, req *messages.Request, role string) ([]byte, error) { log.Println("received provisioning request") box, secret, err := crypto.ProvisionSecret(reqData.Length, reqData.Ident, role) if err != nil { log.Printf("failed to provision secret (%v)", err) return messages.NewServerResponse(false, "Failed to provision secret.", nil) } tx, err := db.Begin() if err != nil { log.Printf("initiating database transaction failed (%v)", err) return messages.NewServerResponse(false, "Failed to provision secret.", nil) } err = db.StoreSecret(tx, box, reqData.Ident, role, req.Public) db.Finalise(tx, err) if err != nil { log.Printf("failed to store secret (%v)", err) return messages.NewServerResponse(false, "Failed to provision secret.", nil) } var response = struct { Secret []byte `json:"secret"` }{secret} out, err := json.Marshal(response) if err != nil { log.Printf("failed to marshal json response (%v)", err) return messages.NewServerResponse(false, "Failed to provision secret.", nil) } return messages.NewServerResponse(true, "Secret provisioned.", out) }
func newRole(tx *sql.Tx, req *messages.Request, adm *messages.AdminRequest, role string) ([]byte, error) { err := db.AddRole(tx, role, adm.Public) if err != nil { log.Printf("failed to create new role (%v)", err) return messages.NewServerResponse(false, "Failed to create role.", nil) } log.Println("role", role, "created successfully") return messages.NewServerResponse(true, "Role created.", nil) }
func initAdmin(tx *sql.Tx, req *messages.Request) ([]byte, error) { log.Println("intialising admin role") err := db.AddRole(tx, "admin", req.Public) if err != nil { log.Printf("failed to initialise admin role (%s)", err) return messages.NewServerResponse(false, "Failed to initialise admin.", nil) } log.Println("admin role initialised") return messages.NewServerResponse(true, "Admin role initialised.", nil) }
func processStore(reqData *messages.RequestData, req *messages.Request, role string) ([]byte, error) { box, err := crypto.SecureSecret(reqData.Secret, reqData.Ident, role) if err != nil { return messages.NewServerResponse(false, "Failed to store secret.", nil) } tx, err := db.Begin() if err != nil { log.Printf("initiating database transaction failed (%v)", err) return messages.NewServerResponse(false, "Failed to store secret.", nil) } err = db.StoreSecret(tx, box, reqData.Ident, role, req.Public) db.Finalise(tx, err) if err != nil { return messages.NewServerResponse(false, "Failed to provision secret.", nil) } return messages.NewServerResponse(true, "Stored secret.", nil) }
func alterRole(role string, req *messages.Request, adm *messages.AdminRequest) ([]byte, error) { tx, err := db.Begin() if err != nil { log.Println("database failure on request") return messages.NewServerResponse(false, "Database failure.", nil) } var out []byte if !db.HaveAdmin(tx) { if role == "admin" { out, err = initAdmin(tx, req) } else { out, err = messages.NewServerResponse(false, "Admin role not initialised.", nil) } } else { out, err = updateRole(tx, req, adm, role) } db.Finalise(tx, err) return out, err }
func updateRole(tx *sql.Tx, req *messages.Request, adm *messages.AdminRequest, role string) ([]byte, error) { log.Println("request to update role as admin") log.Println("checking revocation list") // Check key against revocation list. revoked, err := db.IsKeyRevoked(tx, req.Public) if err != nil { log.Printf("failed to check revocation list (%v)", err) return messages.NewServerResponse(false, "Not authorised.", nil) } else if revoked { log.Println("request attempted with revoked key") return messages.NewServerResponse(false, "Not authorised.", nil) } // Retrieve the admin key, and ensure that the request was properly signed by this key. adminSigner, err := db.GetRoleSigner(tx, "admin") if err != nil { log.Printf("failed to get admin signer (%v)", err) return messages.NewServerResponse(false, "Not authorised.", nil) } // If the role is admin, ensure the key is the admin key. if role == "admin" { if !bytes.Equal(adminSigner, req.Public) { log.Printf("request to change admin role from key that is not admin key") return messages.NewServerResponse(false, "Not authorised.", nil) } } if !crypto.CheckRequestSignature(req, adminSigner) { log.Println("admin request made with bad signature") return messages.NewServerResponse(false, "Not authorised.", nil) } roleSigner, err := db.GetRoleSigner(tx, role) if err != nil { log.Println("failed to get role signer") return messages.NewServerResponse(false, "Not authorised.", nil) } else if roleSigner == nil { log.Println("role does not exist: create new role", role) return newRole(tx, req, adm, role) } err = db.UpdateRoleSigner(tx, adm.Public, role) if err != nil { log.Printf("failed to update role (%v)", err) return messages.NewServerResponse(false, "Failed to update role.", nil) } log.Println("role updated") return messages.NewServerResponse(true, "Role updated.", nil) }
func revokeKey(req *messages.Request, adm *messages.AdminRequest) ([]byte, error) { tx, err := db.Begin() if err != nil { return messages.NewServerResponse(false, "Database failure.", nil) } if !db.HaveAdmin(tx) { db.Finalise(tx, nil) return messages.NewServerResponse(false, "Not initialised.", nil) } // Check key against revocation list. revoked, err := db.IsKeyRevoked(tx, req.Public) if err != nil { log.Printf("failed to check revocation list (%v)", err) db.Finalise(tx, err) return messages.NewServerResponse(false, "Not authorised.", nil) } else if revoked { log.Println("attempt to revoke key using revoked key") db.Finalise(tx, err) return messages.NewServerResponse(false, "Not authorised.", nil) } // Retrieve the admin key, and ensure that the request was // properly signed by this key. Also, check that the key being // revoked is not the administrative signature key. adminSigner, err := db.GetRoleSigner(tx, "admin") if err != nil { log.Println("failed to load admin signer") db.Finalise(tx, err) return messages.NewServerResponse(false, "Not authorised.", nil) } else if bytes.Equal(adminSigner, adm.Public) { log.Println("attempt to revoke current admin signer") db.Finalise(tx, err) return messages.NewServerResponse(false, "Cannot revoke current admin signer.", nil) } err = db.RevokeKey(tx, adm.Public, req.Public, "", "") if err != nil { db.Finalise(tx, err) log.Printf("failed to revoke key (%v)", err) return messages.NewServerResponse(false, "Failed to revoke key.", nil) } db.Finalise(tx, err) log.Println("revoked key") return messages.NewServerResponse(true, "Key revoked.", nil) }
func writeStatus(w http.ResponseWriter, status int) { w.WriteHeader(status) out, _ := messages.NewServerResponse(false, http.StatusText(status), nil) w.Write(out) }
func serverLockOut(w http.ResponseWriter) { w.WriteHeader(http.StatusBadRequest) out, _ := messages.NewServerResponse(false, "This address is locked out.", nil) w.Write(out) }