Skip to content

Commit

Permalink
Merge pull request #30 from williamlin0518/feature/imei-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ianchen0119 authored Jan 20, 2025
2 parents a9867e2 + 01ef6ac commit ac22468
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 17 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
}
47 changes: 30 additions & 17 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",
name: "Complete-Valid-IMEI",
args: args{
buf: []byte{0x3, 0xf1},
// Example encoding for a valid 15-digit IMEI
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32, 0x57, 0x81,
},
},
want: "imei-01",
want: "imei-490154203237518",
wantErr: false,
},
{
name: "PEI-IMEISV-odd",
name: "Complete-Ivalid-IMEI",
args: args{
buf: []byte{0xd, 0x21},
// Not valid 15-digit IMEI: CD(Check Digit) not valid
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32, 0x57, 0x82,
},
},
want: "imeisv-012",
wantErr: false,
},
{
name: "PEI-nil",
wantErr: true,
},
{
name: "PEI-IMEI-len1",
name: "Complete-Valid-IMEISV",
args: args{
buf: []byte{0xb},
buf: []byte{
0x90, 0x87, 0x65, 0x43, 0x21, 0x01, 0x23, 0x45, 0x60,
},
},
want: "imei-0",
want: "imeisv-9785634121032540",
wantErr: false,
},
{
name: "PEI-IMEI-len0",
name: "IMEI-TooLong",
args: args{
buf: []byte{0x3},
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32, 0x57, 0x81, 0x20,
},
},
want: "imei-",
wantErr: false,
wantErr: true,
},
{
name: "IMEI-TooShort",
args: args{
buf: []byte{
0x4b, 0x09, 0x51, 0x24, 0x30, 0x32,
},
},
wantErr: true,
},
}
for _, tt := range tests {
Expand Down

0 comments on commit ac22468

Please sign in to comment.