// Login performs the necessary actions to start an SP initiated login. func (sp *ServiceProvider) InitiateLogin(w http.ResponseWriter) error { acsURL, _ := url.Parse(sp.AcsURL) binding := HTTPRedirectBinding bindingLocation := sp.GetSSOBindingLocation(binding) if bindingLocation == "" { binding = HTTPPostBinding bindingLocation = sp.GetSSOBindingLocation(binding) } req, err := sp.MakeAuthenticationRequest(bindingLocation) if err != nil { return err } relayState := base64.URLEncoding.EncodeToString(randomBytes(42)) state := jwt.New(jwt.GetSigningMethod("HS256")) claims := state.Claims.(jwt.MapClaims) claims["id"] = req.ID signedState, err := state.SignedString(sp.cookieSecret()) if err != nil { return err } http.SetCookie(w, &http.Cookie{ Name: fmt.Sprintf("saml_%s", relayState), Value: signedState, MaxAge: int(MaxIssueDelay.Seconds()), HttpOnly: false, Path: acsURL.Path, }) if binding == HTTPRedirectBinding { redirectURL := req.Redirect(relayState) w.Header().Add("Location", redirectURL.String()) w.WriteHeader(http.StatusFound) return nil } if binding == HTTPPostBinding { w.Header().Set("Content-Security-Policy", ""+ "default-src; "+ "script-src 'sha256-D8xB+y+rJ90RmLdP72xBqEEc0NUatn7yuCND0orkrgk='; "+ "reflected-xss block; "+ "referrer no-referrer;") w.Header().Add("Content-type", "text/html") w.Write([]byte(`<!DOCTYPE html><html><body>`)) w.Write(req.Post(relayState)) w.Write([]byte(`</body></html>`)) return nil } panic("not reached") }
func TestNoneVerify(t *testing.T) { for _, data := range noneTestData { parts := strings.Split(data.tokenString, ".") method := jwt.GetSigningMethod(data.alg) err := method.Verify(strings.Join(parts[0:2], "."), parts[2], data.key) if data.valid && err != nil { t.Errorf("[%v] Error while verifying key: %v", data.name, err) } if !data.valid && err == nil { t.Errorf("[%v] Invalid key passed validation", data.name) } } }
func TestNoneSign(t *testing.T) { for _, data := range noneTestData { if data.valid { parts := strings.Split(data.tokenString, ".") method := jwt.GetSigningMethod(data.alg) sig, err := method.Sign(strings.Join(parts[0:2], "."), data.key) if err != nil { t.Errorf("[%v] Error signing token: %v", data.name, err) } if sig != parts[2] { t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2]) } } } }
func TestRSAVerify(t *testing.T) { keyData, _ := ioutil.ReadFile("test/sample_key.pub") key, _ := jwt.ParseRSAPublicKeyFromPEM(keyData) for _, data := range rsaTestData { parts := strings.Split(data.tokenString, ".") method := jwt.GetSigningMethod(data.alg) err := method.Verify(strings.Join(parts[0:2], "."), parts[2], key) if data.valid && err != nil { t.Errorf("[%v] Error while verifying key: %v", data.name, err) } if !data.valid && err == nil { t.Errorf("[%v] Invalid key passed validation", data.name) } } }
func TestRSASign(t *testing.T) { keyData, _ := ioutil.ReadFile("test/sample_key") key, _ := jwt.ParseRSAPrivateKeyFromPEM(keyData) for _, data := range rsaTestData { if data.valid { parts := strings.Split(data.tokenString, ".") method := jwt.GetSigningMethod(data.alg) sig, err := method.Sign(strings.Join(parts[0:2], "."), key) if err != nil { t.Errorf("[%v] Error signing token: %v", data.name, err) } if sig != parts[2] { t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2]) } } } }
func TestRSAPSSSign(t *testing.T) { var err error key, _ := ioutil.ReadFile("test/sample_key") var rsaPSSKey *rsa.PrivateKey if rsaPSSKey, err = jwt.ParseRSAPrivateKeyFromPEM(key); err != nil { t.Errorf("Unable to parse RSA private key: %v", err) } for _, data := range rsaPSSTestData { if data.valid { parts := strings.Split(data.tokenString, ".") method := jwt.GetSigningMethod(data.alg) sig, err := method.Sign(strings.Join(parts[0:2], "."), rsaPSSKey) if err != nil { t.Errorf("[%v] Error signing token: %v", data.name, err) } if sig == parts[2] { t.Errorf("[%v] Signatures shouldn't match\nnew:\n%v\noriginal:\n%v", data.name, sig, parts[2]) } } } }
func TestECDSASign(t *testing.T) { for _, data := range ecdsaTestData { var err error key, _ := ioutil.ReadFile(data.keys["private"]) var ecdsaKey *ecdsa.PrivateKey if ecdsaKey, err = jwt.ParseECPrivateKeyFromPEM(key); err != nil { t.Errorf("Unable to parse ECDSA private key: %v", err) } if data.valid { parts := strings.Split(data.tokenString, ".") method := jwt.GetSigningMethod(data.alg) sig, err := method.Sign(strings.Join(parts[0:2], "."), ecdsaKey) if err != nil { t.Errorf("[%v] Error signing token: %v", data.name, err) } if sig == parts[2] { t.Errorf("[%v] Identical signatures\nbefore:\n%v\nafter:\n%v", data.name, parts[2], sig) } } } }
func TestECDSAVerify(t *testing.T) { for _, data := range ecdsaTestData { var err error key, _ := ioutil.ReadFile(data.keys["public"]) var ecdsaKey *ecdsa.PublicKey if ecdsaKey, err = jwt.ParseECPublicKeyFromPEM(key); err != nil { t.Errorf("Unable to parse ECDSA public key: %v", err) } parts := strings.Split(data.tokenString, ".") method := jwt.GetSigningMethod(data.alg) err = method.Verify(strings.Join(parts[0:2], "."), parts[2], ecdsaKey) if data.valid && err != nil { t.Errorf("[%v] Error while verifying key: %v", data.name, err) } if !data.valid && err == nil { t.Errorf("[%v] Invalid key passed validation", data.name) } } }