summaryrefslogtreecommitdiffstats
path: root/lib/srp.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/srp.go')
-rw-r--r--lib/srp.go149
1 files changed, 111 insertions, 38 deletions
diff --git a/lib/srp.go b/lib/srp.go
index 18cf5dd..e9417c4 100644
--- a/lib/srp.go
+++ b/lib/srp.go
@@ -1,4 +1,4 @@
-// Copyright © 2022 siddharth <s@ricketyspace.net>
+// Copyright © 2022 siddharth ravikumar <s@ricketyspace.net>
// SPDX-License-Identifier: ISC
package lib
@@ -8,26 +8,6 @@ import "math/big"
// SRP - implementation.
// Reference http://srp.stanford.edu/design.html
-// SRP Client UI - Spec
-//
-// > register s@ricketyspace.net
-// Enter password
-// > ******
-// Registering with server...registered!
-// > login s@ricketyspace.net
-// Enter password
-// > ******
-// Logging in...in!
-// s@ricketyspace.net>
-// s@ricketyspace.net> login s@ricketyspace.net
-// login command not allowed when logged in
-// s@ricketyspace.net> register rsd@gnu.org
-// register command not allowed when logged in
-// s@ricketyspace.net> logout
-// Logging out..out!
-// > register s@ricketyspace.net
-// Already registered!
-
// SRP Server.
type SRPServer struct {
users []*SRPUser
@@ -144,17 +124,26 @@ func NewSRPUser(n, g, k, ident, pass string) (*SRPUser, error) {
return nil, err
}
+ // Compute verifier.
+ user.ComputeVerifier(pass)
+
+ return user, nil
+}
+
+func (user *SRPUser) Ident() string {
+ return user.ident
+}
+
+func (u *SRPUser) ComputeVerifier(pass string) {
// Generate private key `x` from salt+pass
m := make([]byte, 0)
- copy(m, user.salt)
+ copy(m, u.salt)
m = append(m, StrToBytes(pass)...)
- user.h.Message(m)
- user.x.SetBytes(user.h.Hash())
+ u.h.Message(m)
+ u.x.SetBytes(u.h.Hash())
// Generate password verifier `v`
- user.v.Exp(user.g, user.x, user.n)
-
- return user, nil
+ u.v.Exp(u.g, u.x, u.n)
}
func (u *SRPUser) EphemeralKeyGen() {
@@ -193,6 +182,21 @@ func (u *SRPUser) EphemeralKeyPub() (*big.Int, error) {
return pub, nil
}
+func (u *SRPUser) EphemeralKeyPubSimple() (*big.Int, error) {
+ if u.g == nil || u.g.Cmp(big.NewInt(0)) != 1 {
+ return nil, CPError{"g is not initialized"}
+ }
+ if u.b == nil || u.b.Cmp(big.NewInt(0)) != 1 {
+ return nil, CPError{"b is not initialized"}
+ }
+
+ // pub is 'B'
+ pub := new(big.Int)
+ pub.Exp(u.g, u.b, u.n)
+
+ return pub, nil
+}
+
func (u *SRPUser) SetScramblingParam(a *big.Int) error {
b, err := u.EphemeralKeyPub()
if err != nil {
@@ -222,11 +226,27 @@ func (u *SRPUser) SetScramblingParam(a *big.Int) error {
return nil
}
-func (u *SRPUser) ComputeSessionKey(a *big.Int) error {
- if a.Cmp(big.NewInt(0)) != 1 {
- return CPError{"a is invalid"}
+func (u *SRPUser) SetScramblingParamSimple() error {
+ // random 128-bits
+ r, err := RandomBytes(16)
+ if err != nil {
+ return err
}
+ // Set scrambling paramter u
+ u.u = new(big.Int)
+ u.u.SetBytes(r)
+ if u.u.Cmp(big.NewInt(0)) != 1 {
+ return CPError{"u is invalid"}
+ }
+ return nil
+}
+
+func (u *SRPUser) GetScramblingParam() []byte {
+ return u.u.Bytes()
+}
+
+func (u *SRPUser) ComputeSessionKey(a *big.Int) error {
// v^u
vu := new(big.Int)
vu.Exp(u.v, u.u, u.n)
@@ -247,7 +267,10 @@ func (u *SRPUser) ComputeSessionKey(a *big.Int) error {
}
func (u *SRPUser) SessionKeyMacVerify(mac []byte) bool {
- return u.h.MacVerify(u.salt, u.sk, mac)
+ if BytesEqual(HmacSha256(u.sk, u.salt), mac) {
+ return true
+ }
+ return false
}
func (u *SRPUser) LoggedIn() bool {
@@ -370,14 +393,25 @@ func (s *SRPClientSession) SetScramblingParam(b *big.Int) error {
return nil
}
+func (s *SRPClientSession) SetScramblingParamSimple(u []byte) error {
+ if len(u) < 16 {
+ return CPError{"server u is invalid"}
+ }
+
+ // Set scrambling paramter u
+ s.u = new(big.Int)
+ s.u.SetBytes(u)
+ if s.u.Cmp(big.NewInt(0)) != 1 {
+ return CPError{"u is invalid"}
+ }
+ return nil
+}
+
func (s *SRPClientSession) ComputeSessionKey(salt []byte,
pass string, b *big.Int) error {
if len(salt) < 1 {
return CPError{"salt invalid"}
}
- if len(pass) < 1 {
- return CPError{"pass invalid"}
- }
// salt+pass
sp := make([]byte, 0)
@@ -423,12 +457,51 @@ func (s *SRPClientSession) ComputeSessionKey(salt []byte,
return nil
}
-func (s *SRPClientSession) SessionKeyMac(salt []byte) ([]byte, error) {
- if len(s.sk) < 1 {
- return nil, CPError{"sk is invalid"}
+func (s *SRPClientSession) ComputeSessionKeySimple(salt []byte,
+ pass string, b *big.Int) error {
+ if len(salt) < 1 {
+ return CPError{"salt invalid"}
}
+
+ // salt+pass
+ sp := make([]byte, 0)
+ copy(sp, salt)
+ sp = append(sp, StrToBytes(pass)...)
+
+ // x = H(salt+pass)
+ x := new(big.Int)
+ s.h.Message(sp)
+ x.SetBytes(s.h.Hash())
+
+ // u * x
+ ux := new(big.Int)
+ ux.Mul(s.u, x)
+
+ // a + u*x
+ aux := new(big.Int)
+ aux.Add(s.a, ux)
+
+ // S = (B) ^ (a + u*x)
+ sec := new(big.Int)
+ sec.Exp(b, aux, s.n)
+ sb := sec.Bytes()
+
+ // K = H(S)
+ m := make([]byte, 0)
+ m = append(m, sb...)
+ s.h.Message(m)
+ s.sk = s.h.Hash()
+
+ return nil
+}
+
+func (s *SRPClientSession) SetSessionKey(key []byte) {
+ s.sk = key
+}
+
+func (s *SRPClientSession) SessionKeyMac(salt []byte) ([]byte, error) {
if len(salt) < 1 {
return nil, CPError{"salt is invalid"}
}
- return s.h.Mac(salt, s.sk), nil
+ return HmacSha256(s.sk, salt), nil
}