Skip to content

Commit

Permalink
fix: IMEI/IMEISV validation and test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
williamlin0518 committed Jan 8, 2025
1 parent a9867e2 commit db19072
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 22 deletions.
48 changes: 48 additions & 0 deletions nasConvert/MobileIdentity5GS.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"math/bits"
"strconv"
"strings"
"unicode"

"github.com/free5gc/nas/logger"
"github.com/free5gc/nas/nasMessage"
Expand Down Expand Up @@ -282,5 +283,52 @@ func PeiToStringWithError(buf []byte) (string, error) {
digitStr = digitStr[:len(digitStr)-1] // remove the last digit
}

if prefix == "imei-" {
// Validate IMEI before returning
if len(digitStr) != 15 {
return "", fmt.Errorf("invalid IMEI length: expected 15 digits, got %d", len(digitStr))
}
valid, err := ValidateIMEI(digitStr)
if err != nil {
return "", fmt.Errorf("IMEI validation error: %w", err)
}
if !valid {
return "", fmt.Errorf("invalid IMEI checksum")
}
} else{
if len(digitStr) != 16 {
return "", fmt.Errorf("invalid IMEISV length: expected 16 digits, got %d", len(digitStr))
}
}

return prefix + digitStr, nil
}

func ValidateIMEI(imei string) (bool, error) {
// Remove any non-digit characters
cleanIMEI := strings.ReplaceAll(imei, "-", "")
cleanIMEI = strings.ReplaceAll(cleanIMEI, " ", "")

// Check if all characters are digits
for _, char := range cleanIMEI {
if !unicode.IsDigit(char) {
return false, fmt.Errorf("IMEI contains non-digit character: %c", char)
}
}

// Luhn algorithm validation
sum := 0
for i := len(cleanIMEI) - 1; i >= 0; i-- {
digit := int(cleanIMEI[i] - '0')

if (len(cleanIMEI)-i)%2 == 0 {
digit *= 2
if digit > 9 {
digit = digit/10 + digit%10
}
}
sum += digit
}

return sum%10 == 0, nil
}
57 changes: 35 additions & 22 deletions nasConvert/MobileIdentity5GS_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,40 +311,53 @@ func TestPeiToStringWithError(t *testing.T) {
wantErr bool
}{
{
name: "PEI-IMEI-even",
args: args{
buf: []byte{0x3, 0xf1},
},
want: "imei-01",
wantErr: false,
},
name: "Complete-Valid-IMEI",
args: args{
// Example encoding for a valid 15-digit IMEI
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32, 0x57, 0x81,
},
},
want: "imei-490154203237518",
wantErr: false,
},
{
name: "PEI-IMEISV-odd",
name: "Complete-Ivalid-IMEI",
args: args{
// Example encoding for a valid 15-digit IMEI
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32, 0x57, 0x82,
},
},
wantErr: true,
},
{
name: "Complete-Valid-IMEISV",
args: args{
buf: []byte{0xd, 0x21},
buf: []byte{
0x90, 0x87, 0x65, 0x43, 0x21, 0x01, 0x23, 0x45, 0x60,
},
},
want: "imeisv-012",
want: "imeisv-9785634121032540",
wantErr: false,
},
{
name: "PEI-nil",
wantErr: true,
},
{
name: "PEI-IMEI-len1",
name: "IMEI-TooLong",
args: args{
buf: []byte{0xb},
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32, 0x57, 0x81, 0x20,
},
},
want: "imei-0",
wantErr: false,
wantErr: true,
},
{
name: "PEI-IMEI-len0",
name: "IMEI-TooShort",
args: args{
buf: []byte{0x3},
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32,
},
},
want: "imei-",
wantErr: false,
wantErr: true,
},
}
for _, tt := range tests {
Expand Down

0 comments on commit db19072

Please sign in to comment.