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 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) }