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 (
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 {
return status == StatusDone || status == StatusCancelled || status == StatusTimeout
}
......
......@@ -149,7 +149,7 @@ func (session *session) handlePostCommitments(commitments *irma.IssueCommitmentM
for i, cred := range request.Credentials {
id := cred.CredentialTypeID.IssuerIdentifier()
pk, _ := conf.IrmaConfiguration.PublicKey(id, cred.KeyCounter)
sk, _ := privatekey(id)
sk, _ := conf.PrivateKey(id)
issuer := gabi.NewIssuer(sk, pk, one)
proof := commitments.Proofs[i+discloseCount].(*gabi.ProofU)
attributes, err := cred.AttributeList(conf.IrmaConfiguration, 0x03)
......
......@@ -51,7 +51,7 @@ func validateIssuanceRequest(request *irma.IssuanceRequest) error {
for _, cred := range request.Credentials {
// Check that we have the appropriate private key
iss := cred.CredentialTypeID.IssuerIdentifier()
privatekey, err := privatekey(iss)
privatekey, err := conf.PrivateKey(iss)
if err != nil {
return err
}
......@@ -85,16 +85,6 @@ func validateIssuanceRequest(request *irma.IssuanceRequest) error {
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) {
if session.kssProofs == nil {
session.kssProofs = make(map[irma.SchemeManagerIdentifier]*gabi.ProofP)
......
......@@ -64,6 +64,8 @@ type Configuration struct {
Quiet bool `json:"quiet" mapstructure:"quiet"`
LogJSON bool `json:"log_json" mapstructure:"log_json"`
Production bool `json:"production" mapstructure:"production"`
jwtPrivateKey *rsa.PrivateKey
}
......@@ -148,9 +150,23 @@ func (conf *Configuration) initialize() error {
}
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{}}
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 {
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{
AuthenticationMethodHmac: &HmacAuthenticator{hmackeys: map[string]interface{}{}},
AuthenticationMethodPublicKey: &PublicKeyAuthenticator{publickeys: map[string]interface{}{}},
......@@ -174,13 +190,13 @@ func (conf *Configuration) initialize() error {
}
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 {
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 {
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()
......@@ -208,12 +224,17 @@ func (conf *Configuration) initialize() error {
}
replace := "$1:" + strconv.Itoa(port)
conf.URL = string(regexp.MustCompile("(https?://[^/]*):port").ReplaceAll([]byte(conf.URL), []byte(replace)))
separateClientServer := conf.separateClientServer()
if (separateClientServer && clientTlsConf != nil) || (!separateClientServer && tlsConf != nil) {
if strings.HasPrefix(conf.URL, "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
......
......@@ -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
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.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.`
......@@ -154,6 +154,7 @@ using the corresponding "-file" flag.`
flags.CountP("verbose", "v", "verbose (repeatable)")
flags.BoolP("quiet", "q", false, "quiet")
flags.Bool("log-json", false, "Log in JSON format")
flags.Bool("production", false, "Production mode")
flags.Lookup("verbose").Header = `Other options`
return nil
......@@ -169,6 +170,11 @@ func configure(cmd *cobra.Command) error {
return err
}
if viper.GetBool("production") {
viper.SetDefault("no-auth", false)
viper.SetDefault("url", "")
}
// Locate and read configuration file
confpath := viper.GetString("config")
if confpath != "" {
......@@ -218,7 +224,7 @@ func configure(cmd *cobra.Command) error {
Permissions: irmaserver.Permissions{
Disclosing: handlePermission("disclose-perms"),
Signing: handlePermission("sign-perms"),
Issuing: viper.GetStringSlice("issue-perms"),
Issuing: handlePermission("issue-perms"),
},
ListenAddress: viper.GetString("listen-addr"),
Port: viper.GetInt("port"),
......@@ -242,6 +248,8 @@ func configure(cmd *cobra.Command) error {
ClientTlsCertificateFile: viper.GetString("client-tls-cert-file"),
ClientTlsPrivateKey: viper.GetString("client-tls-privkey"),
ClientTlsPrivateKeyFile: viper.GetString("client-tls-privkey-file"),
Production: viper.GetBool("production"),
}
// Handle requestors
......@@ -263,7 +271,7 @@ func configure(cmd *cobra.Command) error {
}
func handlePermission(typ string) []string {
if !viper.IsSet(typ) {
if !viper.IsSet(typ) && (!viper.GetBool("production") || typ != "issue-perms") {
return []string{"*"}
}
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