Skip to content
This repository has been archived by the owner on Jun 6, 2023. It is now read-only.

Changes based on integrating with ADFS, Azure, and PingOne #7

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6d5e7e4
AuthnRequest: don't create 'signature' tag in request if disabled
samv Nov 19, 2015
5b91e34
Suppress redundant XMLNS tags
samv Nov 19, 2015
6e5fbf2
Omit various optional fields if not set
samv Nov 19, 2015
8eb3a7d
Use persistent, not transient Name IDs
samv Nov 19, 2015
263a125
Don't send hi-resolution issue instants
samv Nov 19, 2015
1257662
SAML Response: parse out the SessionIndex
samv Dec 2, 2015
c249968
Permit setting of 'ForceAuthn' in AuthnRequest
samv Dec 2, 2015
5f34f36
Fix a broken test
samv Dec 6, 2015
07a7a6a
Add a 'ParseDecodedString' Response constructor
samv Dec 6, 2015
25b974a
Allow XML Signatures in one more location on responses
samv Dec 6, 2015
22fc0a7
Don't indent AuthnRequests
samv Dec 7, 2015
032c321
Fix an indent
samv Dec 7, 2015
a9e951e
AuthnRequest protocol compliance fix
samv Dec 7, 2015
4437955
Reverse an earlier protocol change
samv Dec 7, 2015
4482c55
Compliance fix in XML Signature boilerplate, use SHA-256
samv Dec 8, 2015
a561308
AuthnRequest: set Destination for signed requests
samv Dec 9, 2015
8ab58f4
Allow AuthnRequests without name ID policy, auth context
samv Dec 10, 2015
663d4f4
Add (limited) support for encrypted response assertions
samv Dec 12, 2015
c097a17
Comment out the debug output
samv Dec 12, 2015
b671544
Fix imports
samv Dec 16, 2015
7947faf
go fmt
samv Dec 16, 2015
0ae90e1
Implement LogoutRequest
samv Dec 16, 2015
661c9fa
Put back the imports
samv Jan 13, 2016
6ccbdcc
Add some XML bindings for Metadata
Mar 28, 2016
a218cc0
Make the codebase parsable
samv Feb 1, 2016
b86f185
PA-22319: Created unit tests and add additional validation for signat…
Jan 16, 2020
9b443e1
ADMIN-2247 - add test key to gitleaks allowed list
mlovrovich Oct 25, 2021
bddad8f
Merge pull request #6 from parsable/ADMIN-2247-gitleaks-allowed-list
mlovrovich Oct 25, 2021
fd8310a
INFRA-2677: GHA pipeline
parsable-brobles Nov 13, 2023
93bb449
INFRA-2677: Add dependabot
parsable-brobles Nov 13, 2023
06bf1c9
INFRA-2677: fix common actions
parsable-brobles Nov 14, 2023
be602a8
INFRA-2677: fix common actions
parsable-brobles Nov 15, 2023
c137aa2
Merge pull request #7 from parsable/infra-2677-buid-gha-pipeline
pbrobles Nov 15, 2023
5001401
INFRA-2677: fix build publish workflow
parsable-brobles Nov 15, 2023
715e1ba
Merge pull request #8 from parsable/infra-2677-build-gha-pipeline
pbrobles Nov 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
PA-22319: Created unit tests and add additional validation for signat…
…ure on response, assertion and encryptedassertion (#3)
Alex Valenzuela authored Jan 16, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit b86f1856283ffa04499603c684aef249f23c78b7
2 changes: 1 addition & 1 deletion authnresponse.go
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ func (r *Response) Validate(s *ServiceProviderSettings) error {
return errors.New("no Assertions")
}

if len(r.Signature.SignatureValue.Value) == 0 {
if len(r.Signature.SignatureValue.Value) == 0 && len(r.Assertion.Signature.SignatureValue.Value) == 0 && len(r.EncryptedAssertion.Assertion.Signature.SignatureValue.Value) == 0 {
return errors.New("no signature")
}

113 changes: 113 additions & 0 deletions authnresponse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package saml

import (
"fmt"
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestResponseSignatureOnResponse(t *testing.T) {
assertion := assert.New(t)
sp := ServiceProviderSettings{
PublicCertPath: "./default.crt",
PrivateKeyPath: "./default.key",
IDPSSOURL: "http://www.onelogin.net",
IDPSSODescriptorURL: "http://www.onelogin.net",
IDPPublicCertPath: "./default.crt",
AssertionConsumerServiceURL: "http://localhost:8000/auth/saml/name",
SPSignRequest: true,
}

err := sp.Init()
assertion.NoError(err)

// Construct a SignedResponse
response := NewSignedResponse()

var sURI strings.Builder
sURI.WriteString("#")
sURI.WriteString(response.ID)

response.Signature.SignedInfo.SamlsigReference.URI = sURI.String()

sXml, err := response.String()
assertion.NoError(err)

fmt.Println("Response (XML as String) : ", sXml)

signedXml, err := SignResponse(sXml, "./default.key")
assertion.NoError(err)

fmt.Println("Signed Response (XML as String) : ", sXml)

signedResponse, err := ParseDecodedResponse([]byte(signedXml))
assertion.NoError(err)

err = signedResponse.VerifySignature("./default.crt")
assertion.NoError(err)
}

func TestResponseSignatureOnAssertion(t *testing.T) {
assertion := assert.New(t)
sp := ServiceProviderSettings{
PublicCertPath: "./default.crt",
PrivateKeyPath: "./default.key",
IDPSSOURL: "http://www.onelogin.net",
IDPSSODescriptorURL: "http://www.onelogin.net",
IDPPublicCertPath: "./default.crt",
AssertionConsumerServiceURL: "http://localhost:8000/auth/saml/name",
SPSignRequest: true,
}

err := sp.Init()
assertion.NoError(err)

// Construct a SignedResponse
response := NewSignedResponse()

var sURI strings.Builder
sURI.WriteString("#")
sURI.WriteString(response.ID)

response.Assertion.Signature.SignedInfo.SamlsigReference.URI = sURI.String()

sXml, err := response.String()
assertion.NoError(err)

fmt.Println("Response (XML as String) : ", sXml)

signedXml, err := SignResponse(sXml, "./default.key")
assertion.NoError(err)

fmt.Println("Signed Response (XML as String) : ", sXml)

signedResponse, err := ParseDecodedResponse([]byte(signedXml))
assertion.NoError(err)

err = signedResponse.VerifySignature("./default.crt")
assertion.NoError(err)
}

func TestLoadedXmlResponse(t *testing.T) {
assertion := assert.New(t)
sp := ServiceProviderSettings{
PublicCertPath: "./default.crt",
PrivateKeyPath: "./default.key",
IDPSSOURL: "http://www.onelogin.net",
IDPSSODescriptorURL: "http://www.onelogin.net",
IDPPublicCertPath: "./default.crt",
AssertionConsumerServiceURL: "http://localhost:8000/auth/saml/name",
SPSignRequest: true,
}

err := sp.Init()
assertion.NoError(err)

gpXMLResponse, err := LoadXml("./samlresponse.xml") // Feel free to change the Path to whatever your XML Response is
assertion.NoError(err)

err = VerifyResponseSignature(gpXMLResponse, sp.PublicCertPath, "")
assertion.NoError(err)
}
1 change: 1 addition & 0 deletions samlresponse.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<samlp:Response Version="2.0" ID="fso3J3gur11OlRb3iygthyi90rg" IssueInstant="2019-08-09T21:01:47.444Z" InResponseTo="WI_ed8fb9e4874049d5a8dabff4977f4c85" Destination="https://api.parsable.net/sso/saml/reply" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://auth.kochid.com</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#fso3J3gur11OlRb3iygthyi90rg"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>sXsSLWX4wRQbU8WEoWLHDli+L1dlKJYTUmqiREYfT/I=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>fb2K++ys6Se5t9ZcL0K3qfy356rOY26LqQbUTv6VQGMsKQ/RScwkpE5vbFgJaiyrw9xNvD8ZK2FwieB1gMqJUsnVRPQiuYIulrKZfNQn1oFwSFhDrRD/wUdtdia7+afSspYlid6Gc5qieTiVdl2OI8rpfNeF9T399N4HB2ZR9pcjuGvTBspQVRPHAsGVQhK80LStSD8Gtk7xRKILKSl+J/+wtEpRTVE0BtzP+oRuaFvEn65ACUWOVW12liIJUawjGq9t6rPaq/bzVYrdA4Zu/yB10wa/3ZH1COyAF9h1U/W6vu70F8SoARW957F2chFrJVuMzTPNkdGQOlb/RNv0VQ==</ds:SignatureValue></ds:Signature><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertion ID="qSUZy6lG8Nk7nDQYsLuC04aHueb" IssueInstant="2019-08-09T21:01:47.628Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"><saml:Issuer>https://auth.kochid.com</saml:Issuer><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">[email protected]</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData Recipient="https://api.parsable.net/sso/saml/reply" NotOnOrAfter="2019-08-09T21:06:47.628Z" InResponseTo="WI_ed8fb9e4874049d5a8dabff4977f4c85"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2019-08-09T20:56:47.628Z" NotOnOrAfter="2019-08-09T21:06:47.628Z"><saml:AudienceRestriction><saml:Audience>https://go.parsable.com</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement SessionIndex="qSUZy6lG8Nk7nDQYsLuC04aHueb" AuthnInstant="2019-08-09T21:01:47.530Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Telephony</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name="firstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">COLIN</saml:AttributeValue></saml:Attribute><saml:Attribute Name="lastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">DAWSON</saml:AttributeValue></saml:Attribute><saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">[email protected]</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion></samlp:Response>
14 changes: 11 additions & 3 deletions xmlsec.go
Original file line number Diff line number Diff line change
@@ -9,9 +9,9 @@ import (
)

const (
xmlResponseID = "urn:oasis:names:tc:SAML:2.0:protocol:Response"
xmlRequestID = "urn:oasis:names:tc:SAML:2.0:protocol:AuthnRequest"
xmlLogoutRequestID = "urn:oasis:names:tc:SAML:2.0:protocol:LogoutRequest"
xmlResponseID = "urn:oasis:names:tc:SAML:2.0:protocol:Response"
xmlRequestID = "urn:oasis:names:tc:SAML:2.0:protocol:AuthnRequest"
xmlLogoutRequestID = "urn:oasis:names:tc:SAML:2.0:protocol:LogoutRequest"
)

// SignRequest sign a SAML 2.0 AuthnRequest
@@ -134,3 +134,11 @@ func Decrypt(xml string, privateKeyPath string) ([]byte, error) {
func deleteTempFile(filename string) {
_ = os.Remove(filename)
}

func LoadXml(certPath string) (string, error) {
bXML, err := ioutil.ReadFile(certPath)
if err != nil {
return "", err
}
return string(bXML), nil
}
2 changes: 1 addition & 1 deletion xmlsec_test.go
Original file line number Diff line number Diff line change
@@ -46,6 +46,6 @@ func TestResponse(t *testing.T) {
assert.NoError(err)
assert.NotEmpty(signedXml)

err = VerifyRequestSignature(signedXml, "./default.crt")
err = VerifyResponseSignature(signedXml, "./default.crt", "")
assert.NoError(err)
}