Commit f2155fb2 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Add production mode with stricter defaults

parent 8a06c1f3
...@@ -65,6 +65,31 @@ const ( ...@@ -65,6 +65,31 @@ const (
StatusTimeout Status = "TIMEOUT" // Session timed out StatusTimeout Status = "TIMEOUT" // Session timed out
) )
func (conf *Configuration) PrivateKey(id irma.IssuerIdentifier) (sk *gabi.PrivateKey, err error) {
sk = conf.IssuerPrivateKeys[id]
if sk == nil {
if sk, err = conf.IrmaConfiguration.PrivateKey(id); err != nil {
return nil, err
}
}
return sk, nil
}
func (conf *Configuration) HavePrivateKeys() (bool, error) {
var err error
var sk *gabi.PrivateKey
for id := range conf.IrmaConfiguration.Issuers {
sk, err = conf.PrivateKey(id)
if err != nil {
return false, err
}
if sk != nil {
return true, nil
}
}
return false, nil
}
func (status Status) Finished() bool { func (status Status) Finished() bool {
return status == StatusDone || status == StatusCancelled || status == StatusTimeout return status == StatusDone || status == StatusCancelled || status == StatusTimeout
} }
......
...@@ -149,7 +149,7 @@ func (session *session) handlePostCommitments(commitments *irma.IssueCommitmentM ...@@ -149,7 +149,7 @@ func (session *session) handlePostCommitments(commitments *irma.IssueCommitmentM
for i, cred := range request.Credentials { for i, cred := range request.Credentials {
id := cred.CredentialTypeID.IssuerIdentifier() id := cred.CredentialTypeID.IssuerIdentifier()
pk, _ := conf.IrmaConfiguration.PublicKey(id, cred.KeyCounter) pk, _ := conf.IrmaConfiguration.PublicKey(id, cred.KeyCounter)
sk, _ := privatekey(id) sk, _ := conf.PrivateKey(id)
issuer := gabi.NewIssuer(sk, pk, one) issuer := gabi.NewIssuer(sk, pk, one)
proof := commitments.Proofs[i+discloseCount].(*gabi.ProofU) proof := commitments.Proofs[i+discloseCount].(*gabi.ProofU)
attributes, err := cred.AttributeList(conf.IrmaConfiguration, 0x03) attributes, err := cred.AttributeList(conf.IrmaConfiguration, 0x03)
......
...@@ -51,7 +51,7 @@ func validateIssuanceRequest(request *irma.IssuanceRequest) error { ...@@ -51,7 +51,7 @@ func validateIssuanceRequest(request *irma.IssuanceRequest) error {
for _, cred := range request.Credentials { for _, cred := range request.Credentials {
// Check that we have the appropriate private key // Check that we have the appropriate private key
iss := cred.CredentialTypeID.IssuerIdentifier() iss := cred.CredentialTypeID.IssuerIdentifier()
privatekey, err := privatekey(iss) privatekey, err := conf.PrivateKey(iss)
if err != nil { if err != nil {
return err return err
} }
...@@ -85,16 +85,6 @@ func validateIssuanceRequest(request *irma.IssuanceRequest) error { ...@@ -85,16 +85,6 @@ func validateIssuanceRequest(request *irma.IssuanceRequest) error {
return nil return nil
} }
func privatekey(id irma.IssuerIdentifier) (sk *gabi.PrivateKey, err error) {
sk = conf.IssuerPrivateKeys[id]
if sk == nil {
if sk, err = conf.IrmaConfiguration.PrivateKey(id); err != nil {
return nil, err
}
}
return sk, nil
}
func (session *session) getProofP(commitments *irma.IssueCommitmentMessage, scheme irma.SchemeManagerIdentifier) (*gabi.ProofP, error) { func (session *session) getProofP(commitments *irma.IssueCommitmentMessage, scheme irma.SchemeManagerIdentifier) (*gabi.ProofP, error) {
if session.kssProofs == nil { if session.kssProofs == nil {
session.kssProofs = make(map[irma.SchemeManagerIdentifier]*gabi.ProofP) session.kssProofs = make(map[irma.SchemeManagerIdentifier]*gabi.ProofP)
......
...@@ -64,6 +64,8 @@ type Configuration struct { ...@@ -64,6 +64,8 @@ type Configuration struct {
Quiet bool `json:"quiet" mapstructure:"quiet"` Quiet bool `json:"quiet" mapstructure:"quiet"`
LogJSON bool `json:"log_json" mapstructure:"log_json"` LogJSON bool `json:"log_json" mapstructure:"log_json"`
Production bool `json:"production" mapstructure:"production"`
jwtPrivateKey *rsa.PrivateKey jwtPrivateKey *rsa.PrivateKey
} }
...@@ -148,9 +150,23 @@ func (conf *Configuration) initialize() error { ...@@ -148,9 +150,23 @@ func (conf *Configuration) initialize() error {
} }
if conf.DisableRequestorAuthentication { if conf.DisableRequestorAuthentication {
conf.Logger.Warn("Authentication of incoming session requests disabled: anyone who can reach this server can use it")
authenticators = map[AuthenticationMethod]Authenticator{AuthenticationMethodNone: NilAuthenticator{}} authenticators = map[AuthenticationMethod]Authenticator{AuthenticationMethodNone: NilAuthenticator{}}
conf.Logger.Warn("Authentication of incoming session requests disabled: anyone who can reach this server can use it")
havekeys, err := conf.HavePrivateKeys()
if err != nil {
return err
}
if len(conf.Permissions.Issuing) > 0 && havekeys {
if conf.separateClientServer() || !conf.Production {
conf.Logger.Warn("Issuance enabled and private keys installed: anyone who can reach this server can use it to issue attributes")
} else {
return errors.New("If issuing is enabled in production mode, requestor authentication must be enabled, or client_listen_addr and client_port must be used")
}
}
} else { } else {
if len(conf.Requestors) == 0 {
return errors.New("No requestors configured; either configure one or more requestors or disable requestor authentication")
}
authenticators = map[AuthenticationMethod]Authenticator{ authenticators = map[AuthenticationMethod]Authenticator{
AuthenticationMethodHmac: &HmacAuthenticator{hmackeys: map[string]interface{}{}}, AuthenticationMethodHmac: &HmacAuthenticator{hmackeys: map[string]interface{}{}},
AuthenticationMethodPublicKey: &PublicKeyAuthenticator{publickeys: map[string]interface{}{}}, AuthenticationMethodPublicKey: &PublicKeyAuthenticator{publickeys: map[string]interface{}{}},
...@@ -174,13 +190,13 @@ func (conf *Configuration) initialize() error { ...@@ -174,13 +190,13 @@ func (conf *Configuration) initialize() error {
} }
if conf.ClientPort != 0 && conf.ClientPort == conf.Port { if conf.ClientPort != 0 && conf.ClientPort == conf.Port {
return errors.New("If clientport is given it must be different from port") return errors.New("If client_port is given it must be different from port")
} }
if conf.ClientPort < 0 || conf.ClientPort > 65535 { if conf.ClientPort < 0 || conf.ClientPort > 65535 {
return errors.Errorf("clientport must be between 0 and 65535 (was %d)", conf.ClientPort) return errors.Errorf("client_port must be between 0 and 65535 (was %d)", conf.ClientPort)
} }
if conf.ClientListenAddress != "" && conf.ClientPort == 0 { if conf.ClientListenAddress != "" && conf.ClientPort == 0 {
return errors.New("clientlistenaddr must be combined with a nonzero clientport") return errors.New("client_listen_addr must be combined with a nonzero clientport")
} }
tlsConf, err := conf.tlsConfig() tlsConf, err := conf.tlsConfig()
...@@ -208,12 +224,17 @@ func (conf *Configuration) initialize() error { ...@@ -208,12 +224,17 @@ func (conf *Configuration) initialize() error {
} }
replace := "$1:" + strconv.Itoa(port) replace := "$1:" + strconv.Itoa(port)
conf.URL = string(regexp.MustCompile("(https?://[^/]*):port").ReplaceAll([]byte(conf.URL), []byte(replace))) conf.URL = string(regexp.MustCompile("(https?://[^/]*):port").ReplaceAll([]byte(conf.URL), []byte(replace)))
separateClientServer := conf.separateClientServer() separateClientServer := conf.separateClientServer()
if (separateClientServer && clientTlsConf != nil) || (!separateClientServer && tlsConf != nil) { if (separateClientServer && clientTlsConf != nil) || (!separateClientServer && tlsConf != nil) {
if strings.HasPrefix(conf.URL, "http://") { if strings.HasPrefix(conf.URL, "http://") {
conf.URL = "https://" + conf.URL[len("http://"):] conf.URL = "https://" + conf.URL[len("http://"):]
} }
} }
if !strings.HasPrefix(conf.URL, "https://") {
conf.Logger.Warnf("TLS is not enabled on the url \"%s\" to which the IRMA app will connect. "+
"Ensure that attributes are encrypted in transit by either enabling TLS or adding TLS in a reverse proxy.", conf.URL)
}
} }
return nil return nil
......
...@@ -118,7 +118,7 @@ func setFlags(cmd *cobra.Command) error { ...@@ -118,7 +118,7 @@ func setFlags(cmd *cobra.Command) error {
then the endpoints at /session for the requestor and /irma for the irmaclient (i.e. IRMA app) will listen on then the endpoints at /session for the requestor and /irma for the irmaclient (i.e. IRMA app) will listen on
distinct network endpoints (e.g., localhost:1234/session and 0.0.0.0:5678/irma).` distinct network endpoints (e.g., localhost:1234/session and 0.0.0.0:5678/irma).`
flags.Bool("no-auth", false, "whether or not to authenticate requestors") flags.Bool("no-auth", true, "whether or not to authenticate requestors")
flags.String("requestors", "", "requestor configuration (in JSON)") flags.String("requestors", "", "requestor configuration (in JSON)")
flags.Lookup("no-auth").Header = `Requestor authentication. If disabled, then anyone that can reach this server can submit requests to it. flags.Lookup("no-auth").Header = `Requestor authentication. If disabled, then anyone that can reach this server can submit requests to it.
If it is enabled, then requestor specific configuration must be provided.` If it is enabled, then requestor specific configuration must be provided.`
...@@ -154,6 +154,7 @@ using the corresponding "-file" flag.` ...@@ -154,6 +154,7 @@ using the corresponding "-file" flag.`
flags.CountP("verbose", "v", "verbose (repeatable)") flags.CountP("verbose", "v", "verbose (repeatable)")
flags.BoolP("quiet", "q", false, "quiet") flags.BoolP("quiet", "q", false, "quiet")
flags.Bool("log-json", false, "Log in JSON format") flags.Bool("log-json", false, "Log in JSON format")
flags.Bool("production", false, "Production mode")
flags.Lookup("verbose").Header = `Other options` flags.Lookup("verbose").Header = `Other options`
return nil return nil
...@@ -169,6 +170,11 @@ func configure(cmd *cobra.Command) error { ...@@ -169,6 +170,11 @@ func configure(cmd *cobra.Command) error {
return err return err
} }
if viper.GetBool("production") {
viper.SetDefault("no-auth", false)
viper.SetDefault("url", "")
}
// Locate and read configuration file // Locate and read configuration file
confpath := viper.GetString("config") confpath := viper.GetString("config")
if confpath != "" { if confpath != "" {
...@@ -218,7 +224,7 @@ func configure(cmd *cobra.Command) error { ...@@ -218,7 +224,7 @@ func configure(cmd *cobra.Command) error {
Permissions: irmaserver.Permissions{ Permissions: irmaserver.Permissions{
Disclosing: handlePermission("disclose-perms"), Disclosing: handlePermission("disclose-perms"),
Signing: handlePermission("sign-perms"), Signing: handlePermission("sign-perms"),
Issuing: viper.GetStringSlice("issue-perms"), Issuing: handlePermission("issue-perms"),
}, },
ListenAddress: viper.GetString("listen-addr"), ListenAddress: viper.GetString("listen-addr"),
Port: viper.GetInt("port"), Port: viper.GetInt("port"),
...@@ -242,6 +248,8 @@ func configure(cmd *cobra.Command) error { ...@@ -242,6 +248,8 @@ func configure(cmd *cobra.Command) error {
ClientTlsCertificateFile: viper.GetString("client-tls-cert-file"), ClientTlsCertificateFile: viper.GetString("client-tls-cert-file"),
ClientTlsPrivateKey: viper.GetString("client-tls-privkey"), ClientTlsPrivateKey: viper.GetString("client-tls-privkey"),
ClientTlsPrivateKeyFile: viper.GetString("client-tls-privkey-file"), ClientTlsPrivateKeyFile: viper.GetString("client-tls-privkey-file"),
Production: viper.GetBool("production"),
} }
// Handle requestors // Handle requestors
...@@ -263,7 +271,7 @@ func configure(cmd *cobra.Command) error { ...@@ -263,7 +271,7 @@ func configure(cmd *cobra.Command) error {
} }
func handlePermission(typ string) []string { func handlePermission(typ string) []string {
if !viper.IsSet(typ) { if !viper.IsSet(typ) && (!viper.GetBool("production") || typ != "issue-perms") {
return []string{"*"} return []string{"*"}
} }
perms := viper.GetStringSlice(typ) perms := viper.GetStringSlice(typ)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment