Skip to content

Commit fcc2cc5

Browse files
committed
implement query signature verification
add support for sha1 & sha512 add tests
1 parent 5e0ffd2 commit fcc2cc5

File tree

4 files changed

+329
-4
lines changed

4 files changed

+329
-4
lines changed

service_provider.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,19 @@ func (req *AuthnRequest) Redirect(relayState string, sp *ServiceProvider) (*url.
259259

260260
rv, _ := url.Parse(req.Destination)
261261
// We can't depend on Query().set() as order matters for signing
262+
reqString := string(w.Bytes())
262263
query := rv.RawQuery
263264
if len(query) > 0 {
264-
query += "&SAMLRequest=" + url.QueryEscape(string(w.Bytes()))
265+
query += "&" + string(samlRequest) + "=" + url.QueryEscape(reqString)
265266
} else {
266-
query += "SAMLRequest=" + url.QueryEscape(string(w.Bytes()))
267+
query += string(samlRequest) + "=" + url.QueryEscape(reqString)
267268
}
268269

269270
if relayState != "" {
270271
query += "&RelayState=" + relayState
271272
}
272273
if len(sp.SignatureMethod) > 0 {
274+
sp.signQuery(samlRequest, query, reqString, relayState)
273275
query += "&SigAlg=" + url.QueryEscape(sp.SignatureMethod)
274276
signingContext, err := GetSigningContext(sp)
275277

@@ -1484,7 +1486,7 @@ func (sp *ServiceProvider) nameIDFormat() string {
14841486
// ValidateLogoutResponseRequest validates the LogoutResponse content from the request
14851487
func (sp *ServiceProvider) ValidateLogoutResponseRequest(req *http.Request) error {
14861488
if data := req.URL.Query().Get("SAMLResponse"); data != "" {
1487-
return sp.ValidateLogoutResponseRedirect(data)
1489+
return sp.ValidateLogoutResponseRedirect(req.URL.Query())
14881490
}
14891491

14901492
err := req.ParseForm()
@@ -1529,7 +1531,8 @@ func (sp *ServiceProvider) ValidateLogoutResponseForm(postFormData string) error
15291531
//
15301532
// URL Binding appears to be gzip / flate encoded
15311533
// See https://www.oasis-open.org/committees/download.php/20645/sstc-saml-tech-overview-2%200-draft-10.pdf 6.6
1532-
func (sp *ServiceProvider) ValidateLogoutResponseRedirect(queryParameterData string) error {
1534+
func (sp *ServiceProvider) ValidateLogoutResponseRedirect(query url.Values) error {
1535+
queryParameterData := query.Get("SAMLResponse")
15331536
rawResponseBuf, err := base64.StdEncoding.DecodeString(queryParameterData)
15341537
if err != nil {
15351538
return fmt.Errorf("unable to parse base64: %s", err)
@@ -1562,6 +1565,10 @@ func (sp *ServiceProvider) ValidateLogoutResponseRedirect(queryParameterData str
15621565
return err
15631566
}
15641567

1568+
if query.Get("Signature") != "" && query.Get("SigAlg") != "" {
1569+
return sp.validateQuerySig(query)
1570+
}
1571+
15651572
responseEl := doc.Root()
15661573
return sp.validateSigned(responseEl)
15671574
}

service_provider_signed.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package saml
2+
3+
import (
4+
"crypto"
5+
"crypto/rsa"
6+
"crypto/sha1" // #nosec G505
7+
"crypto/sha256"
8+
"crypto/sha512"
9+
"crypto/x509"
10+
"encoding/base64"
11+
"errors"
12+
"fmt"
13+
"net/url"
14+
15+
dsig "github.com/russellhaering/goxmldsig"
16+
)
17+
18+
type reqType string
19+
20+
const (
21+
samlRequest reqType = "SAMLRequest"
22+
samlResponse reqType = "SAMLResponse"
23+
)
24+
25+
var (
26+
// ErrInvalidQuerySignature is returned when the query signature is invalid
27+
ErrInvalidQuerySignature = errors.New("invalid query signature")
28+
// ErrNoQuerySignature is returned when the query does not contain a signature
29+
ErrNoQuerySignature = errors.New("no query signature present")
30+
)
31+
32+
// Sign Query with the SP private key.
33+
// Returns provided query with the SigAlg and Signature parameters added.
34+
func (sp *ServiceProvider) signQuery(reqT reqType, query, body, relayState string) (string, error) {
35+
signingContext, err := GetSigningContext(sp)
36+
37+
// Encode Query as standard demands. query.Encode() is not standard compliant
38+
toHash := string(reqT) + "=" + url.QueryEscape(body)
39+
if relayState != "" {
40+
toHash += "&RelayState=" + url.QueryEscape(relayState)
41+
}
42+
43+
toHash += "&SigAlg=" + url.QueryEscape(sp.SignatureMethod)
44+
45+
if err != nil {
46+
return "", err
47+
}
48+
49+
sig, err := signingContext.SignString(toHash)
50+
if err != nil {
51+
return "", err
52+
}
53+
54+
query += "&SigAlg=" + url.QueryEscape(sp.SignatureMethod)
55+
query += "&Signature=" + url.QueryEscape(base64.StdEncoding.EncodeToString(sig))
56+
57+
return query, nil
58+
}
59+
60+
// validateSig validation of the signature of the Redirect Binding in query values
61+
// Query is valid if return is nil
62+
func (sp *ServiceProvider) validateQuerySig(query url.Values) error {
63+
sig := query.Get("Signature")
64+
alg := query.Get("SigAlg")
65+
if sig == "" || alg == "" {
66+
return ErrNoQuerySignature
67+
}
68+
69+
certs, err := sp.getIDPSigningCerts()
70+
if err != nil {
71+
return err
72+
}
73+
74+
respType := ""
75+
if query.Get("SAMLResponse") != "" {
76+
respType = "SAMLResponse"
77+
} else if query.Get("SAMLRequest") != "" {
78+
respType = "SAMLRequest"
79+
} else {
80+
return fmt.Errorf("No SAMLResponse or SAMLRequest found in query")
81+
}
82+
83+
// Encode Query as standard demands. query.Encode() is not standard compliant
84+
res := respType + "=" + url.QueryEscape(query.Get(respType))
85+
86+
relayState := query.Get("RelayState")
87+
if relayState != "" {
88+
res += "&RelayState=" + url.QueryEscape(relayState)
89+
}
90+
91+
res += "&SigAlg=" + url.QueryEscape(alg)
92+
93+
// Signature is base64 encoded
94+
sigBytes, err := base64.StdEncoding.DecodeString(sig)
95+
if err != nil {
96+
return err
97+
}
98+
99+
var (
100+
hashed []byte
101+
hashAlg crypto.Hash
102+
sigAlg x509.SignatureAlgorithm
103+
)
104+
105+
// Hashed Query
106+
switch alg {
107+
case dsig.RSASHA256SignatureMethod:
108+
hashed256 := sha256.Sum256([]byte(res))
109+
hashed = hashed256[:]
110+
hashAlg = crypto.SHA256
111+
sigAlg = x509.SHA256WithRSA
112+
case dsig.RSASHA512SignatureMethod:
113+
hashed512 := sha512.Sum512([]byte(res))
114+
hashed = hashed512[:]
115+
hashAlg = crypto.SHA512
116+
sigAlg = x509.SHA512WithRSA
117+
case dsig.RSASHA1SignatureMethod:
118+
hashed1 := sha1.Sum([]byte(res)) // #nosec G401
119+
hashed = hashed1[:]
120+
hashAlg = crypto.SHA1
121+
sigAlg = x509.SHA1WithRSA
122+
}
123+
124+
// validate signature
125+
for _, cert := range certs {
126+
// verify cert is RSA
127+
if cert.SignatureAlgorithm != sigAlg {
128+
continue
129+
}
130+
131+
if err := rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), hashAlg, hashed, sigBytes); err == nil {
132+
return nil
133+
}
134+
}
135+
136+
return ErrInvalidQuerySignature
137+
}

service_provider_signed_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package saml
2+
3+
import (
4+
"crypto/rsa"
5+
"encoding/base64"
6+
"encoding/xml"
7+
"fmt"
8+
"net/url"
9+
"testing"
10+
11+
dsig "github.com/russellhaering/goxmldsig"
12+
"gotest.tools/assert"
13+
"gotest.tools/golden"
14+
)
15+
16+
// Given a SAMLRequest query string, sign the query and validate signature
17+
// Using same Cert for SP and IdP in order to test
18+
func TestSigningAndValidation(t *testing.T) {
19+
type testCase struct {
20+
relayState string
21+
requestType reqType
22+
wantRawQuery string
23+
}
24+
25+
testCases := []testCase{
26+
{
27+
relayState: "AAAAAAAAAAAA",
28+
requestType: samlRequest,
29+
wantRawQuery: "SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJRD0iaWQtMDAwMjA0MDYwODBhMGMwZTEwMTIxNDE2MTgxYTFjMWUyMDIyMjQyNiIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTUtMTItMDFUMDE6NTc6MDlaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9pZHAuZXhhbXBsZS5jb20vc2FtbC9zc28iIEFzc2VydGlvbkNvbnN1bWVyU2VydmljZVVSTD0iaHR0cHM6Ly9zcC5leGFtcGxlLmNvbS9zYW1sMi9hY3MiIFByb3RvY29sQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVCI%2BPHNhbWw6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwczovL3NwLmV4YW1wbGUuY29tL3NhbWwyL21ldGFkYXRhPC9zYW1sOklzc3Vlcj48c2FtbHA6TmFtZUlEUG9saWN5IEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50IiBBbGxvd0NyZWF0ZT0idHJ1ZSIvPjwvc2FtbHA6QXV0aG5SZXF1ZXN0Pg%3D%3D&RelayState=AAAAAAAAAAAA&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=zWAF4S%2FIs7tfmEriOsT5Fm8EFOGS3iCq6OxP5i7hM%2BMPwAoXwdDz6fKH8euS1gQ3sGOZBdHD588FZLvnO1OeCxLaEsxHMVKsAZSZFLBmPPwqB6e%2B84cCwX2szOeoMROaR%2B36mdoBDRQz36JIvyBBG%2FND9x41k%2FGQuAuwk%2B9fkuE%3D",
30+
},
31+
{
32+
relayState: "",
33+
requestType: samlRequest,
34+
wantRawQuery: "SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJRD0iaWQtMDAwMjA0MDYwODBhMGMwZTEwMTIxNDE2MTgxYTFjMWUyMDIyMjQyNiIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTUtMTItMDFUMDE6NTc6MDlaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9pZHAuZXhhbXBsZS5jb20vc2FtbC9zc28iIEFzc2VydGlvbkNvbnN1bWVyU2VydmljZVVSTD0iaHR0cHM6Ly9zcC5leGFtcGxlLmNvbS9zYW1sMi9hY3MiIFByb3RvY29sQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVCI%2BPHNhbWw6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwczovL3NwLmV4YW1wbGUuY29tL3NhbWwyL21ldGFkYXRhPC9zYW1sOklzc3Vlcj48c2FtbHA6TmFtZUlEUG9saWN5IEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50IiBBbGxvd0NyZWF0ZT0idHJ1ZSIvPjwvc2FtbHA6QXV0aG5SZXF1ZXN0Pg%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=HDdoHJSdkYh9%2BmE7RZ1LXcsAWIMJ6LuzKJgwLxH%2BQ4sKFlh8b5moFuQ%2B7rPEwoTcg9SjgCGV5rW9v8PrSU7WGKcLfAbeVwXWyU94ghjFZHEj%2BFCDpsfTD750ZPAPVnhVr0GogFZZ7c%2BEWX4NAqL4CYxDvsg56o%2BpOjw62G%2FyPDc%3D",
35+
},
36+
{
37+
relayState: "AAAAAAAAAAAA",
38+
requestType: samlResponse,
39+
wantRawQuery: "SAMLResponse=PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJRD0iaWQtMDAwMjA0MDYwODBhMGMwZTEwMTIxNDE2MTgxYTFjMWUyMDIyMjQyNiIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMTUtMTItMDFUMDE6NTc6MDlaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9pZHAuZXhhbXBsZS5jb20vc2FtbC9zc28iIEFzc2VydGlvbkNvbnN1bWVyU2VydmljZVVSTD0iaHR0cHM6Ly9zcC5leGFtcGxlLmNvbS9zYW1sMi9hY3MiIFByb3RvY29sQmluZGluZz0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmJpbmRpbmdzOkhUVFAtUE9TVCI%2BPHNhbWw6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwczovL3NwLmV4YW1wbGUuY29tL3NhbWwyL21ldGFkYXRhPC9zYW1sOklzc3Vlcj48c2FtbHA6TmFtZUlEUG9saWN5IEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6dHJhbnNpZW50IiBBbGxvd0NyZWF0ZT0idHJ1ZSIvPjwvc2FtbHA6QXV0aG5SZXF1ZXN0Pg%3D%3D&RelayState=AAAAAAAAAAAA&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=JDeiWfLgV7SZqgqU64wgtAHS%2FqtF2c3c%2B9g1vdfRHn03tm5jrgsvJtIYg1BD8HoejCoyruH3xgDz1i2qqecVcUiAdaVgVvhn0JWJ%2BzeN9YpUFTEQ4Ah1pwezlSArzuz5esgYzSkemViox313HePWZ%2Fd0FAmtdXuGHA8O0Lp%2F4Ws%3D",
40+
},
41+
}
42+
43+
idpMetadata := golden.Get(t, "SP_IDPMetadata_signing")
44+
s := ServiceProvider{
45+
Key: mustParsePrivateKey(golden.Get(t, "idp_key.pem")).(*rsa.PrivateKey),
46+
Certificate: mustParseCertificate(golden.Get(t, "idp_cert.pem")),
47+
MetadataURL: mustParseURL("https://15661444.ngrok.io/saml2/metadata"),
48+
AcsURL: mustParseURL("https://15661444.ngrok.io/saml2/acs"),
49+
SignatureMethod: dsig.RSASHA1SignatureMethod,
50+
}
51+
52+
err := xml.Unmarshal(idpMetadata, &s.IDPMetadata)
53+
idpCert, err := s.getIDPSigningCerts()
54+
55+
assert.Check(t, err == nil)
56+
assert.Check(t,
57+
s.Certificate.Issuer.CommonName == idpCert[0].Issuer.CommonName, "expected %s, got %s",
58+
s.Certificate.Issuer.CommonName, idpCert[0].Issuer.CommonName)
59+
60+
req := golden.Get(t, "idp_authn_request.xml")
61+
reqString := base64.StdEncoding.EncodeToString(req)
62+
63+
for _, tc := range testCases {
64+
t.Run(fmt.Sprintf("%s_%s", tc.relayState, tc.requestType), func(t *testing.T) {
65+
relayState := tc.relayState
66+
67+
rawQuery := string(tc.requestType) + "=" + url.QueryEscape(reqString)
68+
69+
if relayState != "" {
70+
rawQuery += "&RelayState=" + relayState
71+
}
72+
73+
rawQuery, err = s.signQuery(tc.requestType, rawQuery, reqString, relayState)
74+
assert.NilError(t, err, "error signing query: %s", err)
75+
76+
assert.Equal(t, tc.wantRawQuery, rawQuery)
77+
78+
query, err := url.ParseQuery(rawQuery)
79+
assert.NilError(t, err, "error parsing query: %s", err)
80+
81+
err = s.validateQuerySig(query)
82+
assert.NilError(t, err, "error validating query: %s", err)
83+
})
84+
}
85+
}

testdata/SP_IDPMetadata_signing

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:mdalg="urn:oasis:names:tc:SAML:metadata:algsupport" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="urn:mace:shibboleth:testshib:two" entityID="https://idp.testshib.org/idp/shibboleth">
3+
<Extensions>
4+
<mdalg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha512" />
5+
<mdalg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#sha384" />
6+
<mdalg:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
7+
<mdalg:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
8+
<mdalg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" />
9+
<mdalg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha384" />
10+
<mdalg:SigningMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
11+
<mdalg:SigningMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
12+
</Extensions>
13+
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0 urn:oasis:names:tc:SAML:2.0:protocol">
14+
<Extensions>
15+
<shibmd:Scope regexp="false">testshib.org</shibmd:Scope>
16+
<mdui:UIInfo>
17+
<mdui:DisplayName xml:lang="en">TestShib Test IdP</mdui:DisplayName>
18+
<mdui:Description xml:lang="en">TestShib IdP. Use this as a source of attributes
19+
for your test SP.</mdui:Description>
20+
<mdui:Logo height="88" width="253">https://www.testshib.org/testshibtwo.jpg</mdui:Logo>
21+
</mdui:UIInfo>
22+
</Extensions>
23+
<KeyDescriptor>
24+
<ds:KeyInfo>
25+
<ds:X509Data>
26+
<ds:X509Certificate>MIIB7zCCAVgCCQDFzbKIp7b3MTANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGEwJV
27+
UzELMAkGA1UECAwCR0ExDDAKBgNVBAoMA2ZvbzESMBAGA1UEAwwJbG9jYWxob3N0
28+
MB4XDTEzMTAwMjAwMDg1MVoXDTE0MTAwMjAwMDg1MVowPDELMAkGA1UEBhMCVVMx
29+
CzAJBgNVBAgMAkdBMQwwCgYDVQQKDANmb28xEjAQBgNVBAMMCWxvY2FsaG9zdDCB
30+
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1PMHYmhZj308kWLhZVT4vOulqx/9
31+
ibm5B86fPWwUKKQ2i12MYtz07tzukPymisTDhQaqyJ8Kqb/6JjhmeMnEOdTvSPmH
32+
O8m1ZVveJU6NoKRn/mP/BD7FW52WhbrUXLSeHVSKfWkNk6S4hk9MV9TswTvyRIKv
33+
Rsw0X/gfnqkroJcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCMMlIO+GNcGekevKgk
34+
akpMdAqJfs24maGb90DvTLbRZRD7Xvn1MnVBBS9hzlXiFLYOInXACMW5gcoRFfeT
35+
QLSouMM8o57h0uKjfTmuoWHLQLi6hnF+cvCsEFiJZ4AbF+DgmO6TarJ8O05t8zvn
36+
OwJlNCASPZRH/JmF8tX0hoHuAQ==</ds:X509Certificate>
37+
</ds:X509Data>
38+
</ds:KeyInfo>
39+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
40+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc" />
41+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
42+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
43+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
44+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
45+
</KeyDescriptor>
46+
<ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://idp.testshib.org:8443/idp/profile/SAML1/SOAP/ArtifactResolution" index="1" />
47+
<ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://idp.testshib.org:8443/idp/profile/SAML2/SOAP/ArtifactResolution" index="2" />
48+
<NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
49+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
50+
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.testshib.org/idp/profile/SAML2/POST/SLO" />
51+
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.testshib.org/idp/profile/SAML2/Redirect/SLO" />
52+
<SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://idp.testshib.org/idp/profile/Shibboleth/SSO" />
53+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://idp.testshib.org/idp/profile/SAML2/POST/SSO" />
54+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO" />
55+
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://idp.testshib.org/idp/profile/SAML2/SOAP/ECP" />
56+
</IDPSSODescriptor>
57+
<AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:oasis:names:tc:SAML:2.0:protocol">
58+
<KeyDescriptor>
59+
<ds:KeyInfo>
60+
<ds:X509Data>
61+
<ds:X509Certificate>MIIB7zCCAVgCCQDFzbKIp7b3MTANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGEwJV
62+
UzELMAkGA1UECAwCR0ExDDAKBgNVBAoMA2ZvbzESMBAGA1UEAwwJbG9jYWxob3N0
63+
MB4XDTEzMTAwMjAwMDg1MVoXDTE0MTAwMjAwMDg1MVowPDELMAkGA1UEBhMCVVMx
64+
CzAJBgNVBAgMAkdBMQwwCgYDVQQKDANmb28xEjAQBgNVBAMMCWxvY2FsaG9zdDCB
65+
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1PMHYmhZj308kWLhZVT4vOulqx/9
66+
ibm5B86fPWwUKKQ2i12MYtz07tzukPymisTDhQaqyJ8Kqb/6JjhmeMnEOdTvSPmH
67+
O8m1ZVveJU6NoKRn/mP/BD7FW52WhbrUXLSeHVSKfWkNk6S4hk9MV9TswTvyRIKv
68+
Rsw0X/gfnqkroJcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCMMlIO+GNcGekevKgk
69+
akpMdAqJfs24maGb90DvTLbRZRD7Xvn1MnVBBS9hzlXiFLYOInXACMW5gcoRFfeT
70+
QLSouMM8o57h0uKjfTmuoWHLQLi6hnF+cvCsEFiJZ4AbF+DgmO6TarJ8O05t8zvn
71+
OwJlNCASPZRH/JmF8tX0hoHuAQ==</ds:X509Certificate>
72+
</ds:X509Data>
73+
</ds:KeyInfo>
74+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
75+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes192-cbc" />
76+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
77+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
78+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
79+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
80+
</KeyDescriptor>
81+
<AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding" Location="https://idp.testshib.org:8443/idp/profile/SAML1/SOAP/AttributeQuery" />
82+
<AttributeService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://idp.testshib.org:8443/idp/profile/SAML2/SOAP/AttributeQuery" />
83+
<NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat>
84+
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
85+
</AttributeAuthorityDescriptor>
86+
<Organization>
87+
<OrganizationName xml:lang="en">TestShib Two Identity Provider</OrganizationName>
88+
<OrganizationDisplayName xml:lang="en">TestShib Two</OrganizationDisplayName>
89+
<OrganizationURL xml:lang="en">http://www.testshib.org/testshib-two/</OrganizationURL>
90+
</Organization>
91+
<ContactPerson contactType="technical">
92+
<GivenName>Nate</GivenName>
93+
<SurName>Klingenstein</SurName>
94+
<EmailAddress>[email protected]</EmailAddress>
95+
</ContactPerson>
96+
</EntityDescriptor>

0 commit comments

Comments
 (0)