Browse Source

Fixed WebID-RSA login; improved logging for auth

deiu 7 years ago
parent
commit
a97ee8ea03
4 changed files with 94 additions and 25 deletions
  1. 1 1
      auth.go
  2. 3 10
      crypto.go
  3. 79 6
      crypto_test.go
  4. 11 8
      webid.go

+ 1 - 1
auth.go

@@ -39,7 +39,7 @@ func (req *httpRequest) authn(w http.ResponseWriter) string {
 		}
 	}
 
-	user, err = WebIDTLSAuth(req.TLS)
+	user, err = WebIDTLSAuth(req)
 	if err != nil {
 		req.Server.debug.Println("WebID-TLS error:", err)
 	}

+ 3 - 10
crypto.go

@@ -4,7 +4,6 @@ import (
 	"crypto"
 	"crypto/rand"
 	"crypto/rsa"
-	"crypto/sha256"
 	"crypto/x509"
 	"encoding/pem"
 	"errors"
@@ -93,7 +92,7 @@ func ParseRSAPublicPEMKey(pemBytes []byte) (Verifier, error) {
 func ParseRSAPrivatePEMKey(pemBytes []byte) (Signer, error) {
 	block, _ := pem.Decode(pemBytes)
 	if block == nil {
-		return nil, errors.New("No key found")
+		return nil, errors.New("No key found or could not decode PEM key")
 	}
 
 	var rawkey interface{}
@@ -134,16 +133,10 @@ func newVerifierFromKey(k interface{}) (Verifier, error) {
 
 // Sign signs data with rsa-sha256
 func (r *rsaPrivKey) Sign(data []byte) ([]byte, error) {
-	h := sha256.New()
-	h.Write(data)
-	d := h.Sum(nil)
-	return rsa.SignPKCS1v15(rand.Reader, r.PrivateKey, crypto.SHA256, d)
+	return rsa.SignPKCS1v15(rand.Reader, r.PrivateKey, crypto.SHA1, data)
 }
 
 // Verify verifies the message using a rsa-sha256 signature
 func (r *rsaPubKey) Verify(message []byte, sig []byte) error {
-	h := sha256.New()
-	h.Write(message)
-	d := h.Sum(nil)
-	return rsa.VerifyPKCS1v15(r.PublicKey, crypto.SHA256, d, sig)
+	return rsa.VerifyPKCS1v15(r.PublicKey, crypto.SHA1, message, sig)
 }

+ 79 - 6
crypto_test.go

@@ -1,13 +1,14 @@
 package gold
 
 import (
+	"crypto/sha1"
 	"encoding/base64"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func TestSignAndVerify(t *testing.T) {
+func TestSignaturesRSA(t *testing.T) {
 	privKey := []byte(`-----BEGIN RSA PRIVATE KEY-----
 MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
 NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
@@ -23,6 +24,7 @@ gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
 G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
 7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
 -----END RSA PRIVATE KEY-----`)
+
 	pubKey := []byte(`-----BEGIN RSA PUBLIC KEY-----
 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
 6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
@@ -30,12 +32,83 @@ Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
 oYi+1hqp1fIekaxsyQIDAQAB
 -----END RSA PUBLIC KEY-----`)
 
+	pubT := "RSAPublicKey"
+	pubN := "c2144346c37df21a2872f76a438d94219740b7eab3c98fe0af7d20bcfaadbc871035eb5405354775df0b824d472ad10776aac05eff6845c9cd83089260d21d4befcfba67850c47b10e7297dd504f477f79bf86cf85511e39b8125e0cad474851c3f1b1ca0fa92ff053c67c94e8b5cfb6c63270a188bed61aa9d5f21e91ac6cc9"
+	pubE := "65537"
+
+	h := `WebID-RSA source="https://deiu.me/Private/", username="https://deiu.me/profile#me", nonce="MTQzODc4MzA5NXxtS1dYcVd4bGRjVXQ2bFVEMXk2NE5KMDU1TFB3Nk9qM2FmMWduMk4tdl9tWDdvZXBtdUJSa1ZMRHE4WWZ1dUE0RlNGeDl0OGt6SGZnbkpZbW5CWE96TUxRamJ6a3xCC-Ik7gERpCBc__l2OK0DxVxyIiLTDVZ7rLIib2MNSQ==", sig="qiTKnXaXgMfGEA2LLCqhFWiB+6T9gXvLR6nO2dCvk71nBoK3MiwLxbsF83uKT81ur9SucDJ2fmjLKPbP9o7NrkYrM45rkPJsXHjbAzHDw2DftKLez5DF70HtDa1rEaUEF1mLrNMGfL4VYea5z15lNNNiDKaJpCwhgeHNB1x2qNY="`
+	_toSign := `https://deiu.me/Private/https://deiu.me/profile#meMTQzODc4MzA5NXxtS1dYcVd4bGRjVXQ2bFVEMXk2NE5KMDU1TFB3Nk9qM2FmMWduMk4tdl9tWDdvZXBtdUJSa1ZMRHE4WWZ1dUE0RlNGeDl0OGt6SGZnbkpZbW5CWE96TUxRamJ6a3xCC-Ik7gERpCBc__l2OK0DxVxyIiLTDVZ7rLIib2MNSQ==`
+	_sig := `qiTKnXaXgMfGEA2LLCqhFWiB+6T9gXvLR6nO2dCvk71nBoK3MiwLxbsF83uKT81ur9SucDJ2fmjLKPbP9o7NrkYrM45rkPJsXHjbAzHDw2DftKLez5DF70HtDa1rEaUEF1mLrNMGfL4VYea5z15lNNNiDKaJpCwhgeHNB1x2qNY=`
+	p, err := ParseDigestAuthorizationHeader(h)
+	assert.NoError(t, err)
+
+	assert.Equal(t, _sig, p.Signature)
+
+	parserPem, perr := ParseRSAPublicPEMKey(pubKey)
+	assert.NoError(t, perr)
+
+	parser, perr := ParseRSAPublicKeyNE(pubT, pubN, pubE)
+	assert.NoError(t, perr)
+
+	signer, err := ParseRSAPrivatePEMKey(privKey)
+	assert.NoError(t, err)
+
+	toSign := p.Source + p.Username + p.Nonce
+	assert.Equal(t, _toSign, toSign)
+
+	claim := sha1.Sum([]byte(toSign))
+	signed, err := signer.Sign(claim[:])
+	assert.NoError(t, err)
+	b64Sig := base64.StdEncoding.EncodeToString(signed)
+	assert.Equal(t, p.Signature, b64Sig)
+
+	// println(p.Source, p.Username, p.Nonce, p.Signature)
+	sig, err := base64.StdEncoding.DecodeString(p.Signature)
+	assert.NoError(t, err)
+
+	err = parser.Verify(claim[:], sig)
+	assert.NoError(t, err)
+
+	sig, err = base64.StdEncoding.DecodeString(_sig)
+	assert.NoError(t, err)
+
+	err = parserPem.Verify(claim[:], sig)
+	assert.NoError(t, err)
+
+	err = parser.Verify(claim[:], sig)
+	assert.NoError(t, err)
+}
+
+func TestSignAndVerify(t *testing.T) {
+	privKey := []byte(`-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
+NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
+UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
+AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
+QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
+kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
+f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
+412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
+mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
+kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
+gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
+G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
+7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
+-----END RSA PRIVATE KEY-----`)
+	pubKey := []byte(`-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
+6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
+Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
+oYi+1hqp1fIekaxsyQIDAQAB
+-----END PUBLIC KEY-----`)
+
 	toSign := "some string"
+	claim := sha1.Sum([]byte(toSign))
 
 	signer, err := ParseRSAPrivatePEMKey(privKey)
 	assert.NoError(t, err)
 
-	signed, err := signer.Sign([]byte(toSign))
+	signed, err := signer.Sign(claim[:])
 	assert.NoError(t, err)
 
 	sig := base64.URLEncoding.EncodeToString(signed)
@@ -44,7 +117,7 @@ oYi+1hqp1fIekaxsyQIDAQAB
 	parser, perr := ParseRSAPublicPEMKey(pubKey)
 	assert.NoError(t, perr)
 
-	err = parser.Verify([]byte(toSign), signed)
+	err = parser.Verify(claim[:], signed)
 	assert.NoError(t, err)
 
 	// check with ParsePublicRSAKey
@@ -55,14 +128,14 @@ oYi+1hqp1fIekaxsyQIDAQAB
 	parser, err = ParseRSAPublicKeyNE(pubT, pubN, pubE)
 	assert.NoError(t, perr)
 
-	err = parser.Verify([]byte(toSign), signed)
+	err = parser.Verify(claim[:], signed)
 	assert.NoError(t, err)
 
 	// check with parse rsa.PublicKey
 	signer, err = ParseRSAPrivateKey(user1k)
 	assert.NoError(t, err)
 
-	signed, err = signer.Sign([]byte(toSign))
+	signed, err = signer.Sign(claim[:])
 	assert.NoError(t, err)
 
 	sig = base64.StdEncoding.EncodeToString(signed)
@@ -71,6 +144,6 @@ oYi+1hqp1fIekaxsyQIDAQAB
 	parser, perr = ParseRSAPublicKey(user1p)
 	assert.NoError(t, perr)
 
-	err = parser.Verify([]byte(toSign), signed)
+	err = parser.Verify(claim[:], signed)
 	assert.NoError(t, err)
 }

+ 11 - 8
webid.go

@@ -4,7 +4,6 @@ import (
 	"crypto/rand"
 	"crypto/rsa"
 	"crypto/sha1"
-	"crypto/tls"
 	"crypto/x509"
 	"encoding/asn1"
 	"encoding/base64"
@@ -69,7 +68,6 @@ func WebIDDigestAuth(req *httpRequest) (string, error) {
 
 	claim := sha1.Sum([]byte(authH.Source + authH.Username + authH.Nonce))
 	signature, err := base64.StdEncoding.DecodeString(authH.Signature)
-
 	if err != nil {
 		return "", errors.New(err.Error() + " in " + authH.Signature)
 	}
@@ -108,11 +106,13 @@ func WebIDDigestAuth(req *httpRequest) (string, error) {
 		return "", err
 	}
 
+	req.debug.Println("Checking for public keys for user", authH.Username)
 	for _, keyT := range g.All(NewResource(authH.Username), ns.cert.Get("key"), nil) {
 		for range g.All(keyT.Object, ns.rdf.Get("type"), ns.cert.Get("RSAPublicKey")) {
+			req.debug.Println("Found RSA key in user's profile", keyT.Object.String())
 			for _, pubP := range g.All(keyT.Object, ns.cert.Get("pem"), nil) {
 				keyP := term2C(pubP.Object).String()
-				// loop through all the PEM keys
+				req.debug.Println("Found matching public key in user's profile", keyP[:10], "...", keyP[len(keyP)-10:len(keyP)])
 				parser, err := ParseRSAPublicPEMKey([]byte(keyP))
 				if err == nil {
 					err = parser.Verify(claim[:], signature)
@@ -120,21 +120,22 @@ func WebIDDigestAuth(req *httpRequest) (string, error) {
 						return authH.Username, nil
 					}
 				}
+				req.debug.Println("Unable to verify signature with key", keyP[:10], "...", keyP[len(keyP)-10:len(keyP)], "-- reason:", err)
 			}
 			// also loop through modulus/exp
 			for _, pubN := range g.All(keyT.Object, ns.cert.Get("modulus"), nil) {
 				keyN := term2C(pubN.Object).String()
 				for _, pubE := range g.All(keyT.Object, ns.cert.Get("exponent"), nil) {
 					keyE := term2C(pubE.Object).String()
-					// println(keyN, keyE)
+					req.debug.Println("Found matching modulus and exponent in user's profile", keyN[:10], "...", keyN[len(keyN)-10:len(keyN)])
 					parser, err := ParseRSAPublicKeyNE("RSAPublicKey", keyN, keyE)
 					if err == nil {
 						err = parser.Verify(claim[:], signature)
-						if err != nil {
-							return "", err
+						if err == nil {
+							return authH.Username, nil
 						}
-						return authH.Username, nil
 					}
+					req.debug.Println("Unable to verify signature with key", keyN[:10], "...", keyN[len(keyN)-10:len(keyN)], "-- reason:", err)
 				}
 			}
 		}
@@ -144,7 +145,8 @@ func WebIDDigestAuth(req *httpRequest) (string, error) {
 }
 
 // WebIDTLSAuth - performs WebID-TLS authentication
-func WebIDTLSAuth(tls *tls.ConnectionState) (uri string, err error) {
+func WebIDTLSAuth(req *httpRequest) (uri string, err error) {
+	tls := req.TLS
 	claim := ""
 	uri = ""
 	err = nil
@@ -235,6 +237,7 @@ func WebIDTLSAuth(tls *tls.ConnectionState) (uri string, err error) {
 				}
 			matchExponent:
 				// found a matching exponent in the profile
+				req.debug.Println("Found matching public modulus and exponent in user's profile")
 				uri = claim
 				webidL.Lock()
 				pkeyURI[pkeyk] = uri