Skip to content

Commit

Permalink
Merge pull request #57 from onelogin/key_rollover_mngmt
Browse files Browse the repository at this point in the history
Improve Key Rollover management
  • Loading branch information
pitbulk authored May 18, 2017
2 parents f7a9652 + 650d2b9 commit 34d22e0
Show file tree
Hide file tree
Showing 21 changed files with 825 additions and 194 deletions.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ Or also we can provide those data in the setting file at the 'x509cert' and the

Sometimes we could need a signature on the metadata published by the SP, in this case we could use the x.509 cert previously mentioned or use a new x.509 cert: metadata.crt and metadata.key.

Use `sp_new.crt` if you are in a key rollover process and you want to
publish that x509certificate on Service Provider metadata.

If you want to create self-signed certs, you can do it at the https://www.samltool.com/self_signed_certs.php service, or using the command:

```bash
Expand Down Expand Up @@ -253,6 +256,15 @@ This is the settings.json file:
// the certs folder. But we can also provide them with the following parameters
"x509cert": "",
"privateKey": ""

/*
* Key rollover
* If you plan to update the SP x509cert and privateKey
* you can define here the new x509cert and it will be
* published on the SP metadata so Identity Providers can
* read them and get ready for rollover.
*/
// 'x509certNew': '',
},

// Identity Provider Data that we want connected with our SP.
Expand Down Expand Up @@ -296,6 +308,22 @@ This is the settings.json file:
*/
// "certFingerprint": "",
// "certFingerprintAlgorithm": "sha1",

/* In some scenarios the IdP uses different certificates for
* signing/encryption, or is under key rollover phase and
* more than one certificate is published on IdP metadata.
* In order to handle that the toolkit offers that parameter.
* (when used, 'x509cert' and 'certFingerprint' values are
* ignored).
*/
// 'x509certMulti': {
// 'signing': [
// '<cert1-string>'
// ],
// 'encryption': [
// '<cert2-string>'
// ]
// }
}
}
```
Expand Down Expand Up @@ -449,6 +477,23 @@ json_data_file.close()
auth = OneLogin_Saml2_Auth(req, settings_data)
```

#### Metadata Based Configuration

The method above requires a little extra work to manually specify attributes about the IdP. (And your SP application)

There's an easier method -- use a metadata exchange. Metadata is just an XML file that defines the capabilities of both the IdP and the SP application. It also contains the X.509 public key certificates which add to the trusted relationship. The IdP administrator can also configure custom settings for an SP based on the metadata.

Using ````parse_remote```` IdP metadata can be obtained and added to the settings withouth further ado.

``
idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote('https://example.com/auth/saml2/idp/metadata')
``

If the Metadata contains several entities, the relevant EntityDescriptor can be specified when retrieving the settings from the IdpMetadataParser by its Entity Id value:

idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote(https://example.com/metadatas, entity_id='idp_entity_id')


#### How load the library ####

In order to use the toolkit library you need to import the file that contains the class that you will need
Expand Down Expand Up @@ -777,6 +822,26 @@ else:
```


### SP Key rollover ###

If you plan to update the SP x509cert and privateKey you can define the new x509cert as $settings['sp']['x509certNew'] and it will be
published on the SP metadata so Identity Providers can read them and get ready for rollover.


### IdP with multiple certificates ###

In some scenarios the IdP uses different certificates for
signing/encryption, or is under key rollover phase and more than one certificate is published on IdP metadata.

In order to handle that the toolkit offers the $settings['idp']['x509certMulti'] parameter.

When that parameter is used, 'x509cert' and 'certFingerprint' values will be ignored by the toolkit.

The 'x509certMulti' is an array with 2 keys:
- 'signing'. An array of certs that will be used to validate IdP signature
- 'encryption' An array with one unique cert that will be used to encrypt data to be sent to the IdP.


### Main classes and methods ###

Described below are the main classes and methods that can be invoked from the SAML2 library.
Expand Down Expand Up @@ -884,14 +949,17 @@ Configuration of the OneLogin Python Toolkit
* ***check_sp_certs*** Checks if the x509 certs of the SP exists and are valid.
* ***get_sp_key*** Returns the x509 private key of the SP.
* ***get_sp_cert*** Returns the x509 public cert of the SP.
* ***get_sp_cert_new*** Returns the future x509 public cert of the SP.
* ***get_idp_cert*** Returns the x509 public cert of the IdP.
* ***get_sp_data*** Gets the SP data.
* ***get_idp_data*** Gets the IdP data.
* ***get_security_data*** Gets security data.
* ***get_contacts*** Gets contacts data.
* ***get_organization*** Gets organization data.
* ***format_idp_cert*** Formats the IdP cert.
* ***format_idp_cert_multi*** Formats all registered IdP certs.
* ***format_sp_cert*** Formats the SP cert.
* ***format_sp_cert_new*** Formats the SP cert new.
* ***format_sp_key*** Formats the private key.
* ***set_strict*** Activates or deactivates the strict mode.
* ***is_strict*** Returns if the 'strict' mode is active.
Expand Down
6 changes: 4 additions & 2 deletions demo-django/saml/certs/README
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ Take care of this folder that could contain private key. Be sure that this folde

Onelogin Python Toolkit expects that certs for the SP could be stored in this folder as:

* sp.key Private Key
* sp.crt Public cert
* sp.key Private Key
* sp.crt Public cert
* sp_new.crt Future Public cert


Also you can use other cert to sign the metadata of the SP using the:

Expand Down
6 changes: 4 additions & 2 deletions demo-flask/saml/certs/README
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ Take care of this folder that could contain private key. Be sure that this folde

Onelogin Python Toolkit expects that certs for the SP could be stored in this folder as:

* sp.key Private Key
* sp.crt Public cert
* sp.key Private Key
* sp.crt Public cert
* sp_new.crt Future Public cert


Also you can use other cert to sign the metadata of the SP using the:

Expand Down
6 changes: 4 additions & 2 deletions demo_pyramid/demo_pyramid/saml/certs/README
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ Take care of this folder that could contain private key. Be sure that this folde

Onelogin Python Toolkit expects that certs for the SP could be stored in this folder as:

* sp.key Private Key
* sp.crt Public cert
* sp.key Private Key
* sp.crt Public cert
* sp_new.crt Future Public cert


Also you can use other cert to sign the metadata of the SP using the:

Expand Down
37 changes: 28 additions & 9 deletions src/onelogin/saml2/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,15 @@ def __validate_signature(self, data, saml_type, raise_exceptions=False):
)
return True

x509cert = self.get_settings().get_idp_cert()
idp_data = self.get_settings().get_idp_data()

if not x509cert:
error_msg = "In order to validate the sign on the %s, the x509cert of the IdP is required" % saml_type
exists_x509cert = 'x509cert' in idp_data and idp_data['x509cert']
exists_multix509sign = 'x509certMulti' in idp_data and \
'signing' in idp_data['x509certMulti'] and \
idp_data['x509certMulti']['signing']

if not (exists_x509cert or exists_multix509sign):
error_msg = 'In order to validate the sign on the %s, the x509cert of the IdP is required' % saml_type
self.__errors.append(error_msg)
raise OneLogin_Saml2_Error(
error_msg,
Expand All @@ -559,15 +564,29 @@ def __validate_signature(self, data, saml_type, raise_exceptions=False):
lowercase_urlencoding
)

if not OneLogin_Saml2_Utils.validate_binary_sign(signed_query,
OneLogin_Saml2_Utils.b64decode(signature),
x509cert,
sign_alg,
self.__settings.is_debug_active()):
if exists_multix509sign:
for cert in idp_data['x509certMulti']['signing']:
if OneLogin_Saml2_Utils.validate_binary_sign(signed_query,
OneLogin_Saml2_Utils.b64decode(signature),
cert,
sign_alg):
return True
raise OneLogin_Saml2_ValidationError(
'Signature validation failed. %s rejected.' % saml_type,
'Signature validation failed. %s rejected' % saml_type,
OneLogin_Saml2_ValidationError.INVALID_SIGNATURE
)
else:
cert = idp_data['x509cert']

if not OneLogin_Saml2_Utils.validate_binary_sign(signed_query,
OneLogin_Saml2_Utils.b64decode(signature),
cert,
sign_alg,
self.__settings.is_debug_active()):
raise OneLogin_Saml2_ValidationError(
'Signature validation failed. %s rejected' % saml_type,
OneLogin_Saml2_ValidationError.INVALID_SIGNATURE
)
return True
except Exception as e:
self.__error_reason = str(e)
Expand Down
Loading

0 comments on commit 34d22e0

Please sign in to comment.