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 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 authenticateRequest(req *messages.Request, role, ident string) bool { tx, err := db.Begin() if err != nil { log.Printf("initiating database transaction failed (%v)", err) return false } // Check key against revocation list. log.Println("checking 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 false } else if revoked { log.Println("request made with revoked key") db.Finalise(tx, err) return false } // Verify that the secret falls under the purported role. secRole, err := db.GetSecretRole(tx, ident) if err != nil { if err != sql.ErrNoRows { log.Printf("failed to retrieve secret's role (%v)", err) db.Finalise(tx, err) } else { log.Println("secret doesn't exist") } } else if secRole != role { log.Printf("request made under a role that didn't match the secret's role") db.Finalise(tx, err) return false } log.Println("getting role signer") signer, err := db.GetRoleSigner(tx, role) if err != nil { log.Printf("failed to retrieve %s signer role (%v)", role, err) db.Finalise(tx, err) return false } else if signer == nil { log.Printf("request made for non-existent role %s", role) db.Finalise(tx, err) return false } db.Finalise(tx, err) return crypto.CheckRequestSignature(req, signer) }
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 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 }