diff --git a/pkg/suci/suci.go b/pkg/suci/suci.go index e133d77..60d8ef4 100644 --- a/pkg/suci/suci.go +++ b/pkg/suci/suci.go @@ -218,6 +218,20 @@ func profileA(input, supiType, privateKey string) (string, error) { return calcSchemeResult(decryptPlainText, supiType), nil } +func checkOnCurve(curve elliptic.Curve, x, y *big.Int) error { + // (0, 0) is the point at infinity by convention. It's ok to operate on it, + // although IsOnCurve is documented to return false for it. See Issue 37294. + if x.Sign() == 0 && y.Sign() == 0 { + return nil + } + + if !curve.IsOnCurve(x, y) { + return fmt.Errorf("crypto/elliptic: attempted operation on invalid point") + } + + return nil +} + func profileB(input, supiType, privateKey string) (string, error) { logger.SuciLog.Infoln("SuciToSupi Profile B") s, hexDecodeErr := hex.DecodeString(input) @@ -271,6 +285,10 @@ func profileB(input, supiType, privateKey string) (string, error) { } // fmt.Printf("xUncom: %x\nyUncom: %x\n", xUncompressed, yUncompressed) + if err := checkOnCurve(elliptic.P256(), xUncompressed, yUncompressed); err != nil { + return "", err + } + // x-coordinate is the shared key decryptSharedKey, _ := elliptic.P256().ScalarMult(xUncompressed, yUncompressed, bHNPriv) // fmt.Printf("deShared: %x\n", decryptSharedKey.Bytes()) diff --git a/pkg/suci/suci_test.go b/pkg/suci/suci_test.go index 0594321..4e72ed4 100644 --- a/pkg/suci/suci_test.go +++ b/pkg/suci/suci_test.go @@ -1,6 +1,9 @@ package suci -import "testing" +import ( + "fmt" + "testing" +) func TestToSupi(t *testing.T) { suciProfiles := []SuciProfile{ @@ -17,30 +20,42 @@ func TestToSupi(t *testing.T) { }, } testCases := []struct { - suci string - expected string + suci string + expectedSupi string + expectedErr error }{ { - suci: "suci-0-208-93-0-0-0-00007487", - expected: "imsi-2089300007487", + suci: "suci-0-208-93-0-0-0-00007487", + expectedSupi: "imsi-2089300007487", + expectedErr: nil, }, { suci: "suci-0-208-93-0-1-1-b2e92f836055a255837debf850b528997ce0201cb82a" + "dfe4be1f587d07d8457dcb02352410cddd9e730ef3fa87", - expected: "imsi-20893001002086", + expectedSupi: "imsi-20893001002086", + expectedErr: nil, }, { suci: "suci-0-208-93-0-2-2-039aab8376597021e855679a9778ea0b67396e68c66d" + "f32c0f41e9acca2da9b9d146a33fc2716ac7dae96aa30a4d", - expected: "imsi-20893001002086", + expectedSupi: "imsi-20893001002086", + expectedErr: nil, + }, + { + suci: "suci-0-208-93-0-2-2-0434a66778799d52fedd9326db4b690d092e05c9ba0ace5b413da" + + "fc0a40aa28ee00a79f790fa4da6a2ece892423adb130dc1b30e270b7d0088bdd716b93894891d5221a74c810d6b9350cc067c76", + expectedSupi: "", + expectedErr: fmt.Errorf("crypto/elliptic: attempted operation on invalid point"), }, } for i, tc := range testCases { supi, err := ToSupi(tc.suci, suciProfiles) if err != nil { - t.Errorf("TC%d err: %+v\n", i, err) - } else if supi != tc.expected { - t.Errorf("TC%d fail: supi[%s], expected[%s]\n", i, supi, tc.expected) + if err.Error() != tc.expectedErr.Error() { + t.Errorf("TC%d fail: err[%s], expected[%s]\n", i, err, tc.expectedErr) + } + } else if supi != tc.expectedSupi { + t.Errorf("TC%d fail: supi[%s], expected[%s]\n", i, supi, tc.expectedSupi) } } }