-
Notifications
You must be signed in to change notification settings - Fork 2
fix: more specific error message #187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| package password | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "crypto/rand" | ||
| "crypto/rsa" | ||
| "encoding/hex" | ||
|
|
@@ -11,7 +12,10 @@ import ( | |
| // EncryptPassword constructs the payload and encrypts it using RSA-PKCS1v15. | ||
| func EncryptPassword(email, password, sessionKey, nHex, eHex string) (string, error) { | ||
| // 1. Construct the payload: [len + val]... | ||
| payload := createPayload(email, password, sessionKey) | ||
| payload, err := createPayload(email, password, sessionKey) | ||
| if err != nil { | ||
| return "", fmt.Errorf("failed to create password payload: %w", err) | ||
| } | ||
|
|
||
| // 2. Parse Public Key from Hex | ||
| pubKey, err := parseRSAPublicKey(nHex, eHex) | ||
|
|
@@ -20,7 +24,7 @@ func EncryptPassword(email, password, sessionKey, nHex, eHex string) (string, er | |
| } | ||
|
|
||
| // 3. Encrypt using RSA-PKCS1-v1.5 | ||
| encryptedBytes, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, []byte(payload)) | ||
| encryptedBytes, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, payload) | ||
| if err != nil { | ||
| return "", fmt.Errorf("failed to encrypt payload: %w", err) | ||
| } | ||
|
|
@@ -30,12 +34,16 @@ func EncryptPassword(email, password, sessionKey, nHex, eHex string) (string, er | |
| } | ||
|
|
||
| // Format: [len(sessionKey) + sessionKey + len(email) + email + len(password) + password] | ||
| func createPayload(email, password, sessionKey string) string { | ||
| return fmt.Sprintf("%c%s%c%s%c%s", | ||
| len(sessionKey), sessionKey, | ||
| len(email), email, | ||
| len(password), password, | ||
| ) | ||
| func createPayload(email, password, sessionKey string) ([]byte, error) { | ||
| var payload bytes.Buffer | ||
| for _, field := range []string{sessionKey, email, password} { | ||
| if len(field) > 255 { | ||
| return nil, fmt.Errorf("field is too long: %d bytes", len(field)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Identify the offending field: when this fires the user / log reader has no way to tell whether the server-supplied for _, f := range []struct{ name, value string }{
{"sessionKey", sessionKey},
{"email", email},
{"password", password},
} {
if len(f.value) > 255 {
return nil, fmt.Errorf("%s is too long: %d bytes (max 255)", f.name, len(f.value))
}
payload.WriteByte(byte(len(f.value)))
payload.WriteString(f.value)
}(Make sure not to log the field value — only the name and length.) |
||
| } | ||
| payload.WriteByte(byte(len(field))) | ||
| payload.WriteString(field) | ||
| } | ||
| return payload.Bytes(), nil | ||
| } | ||
|
|
||
| // parseRSAPublicKey converts hex modulus and exponent into *rsa.PublicKey. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Brittle exact-string match:
strings.EqualFoldagainst the literalAccount ID or password is invalidonly fires when LINE returns that exact phrase. Thedata.reasonfield extracted byloginErrorReasonis user-facing text from LINE and has historically changed wording across locales/versions; the moment it does (e.g.Invalid account ID or password, or a localized variant), this branch is skipped and users get the generic copy that this PR is specifically trying to avoid. Consider matching on a substring (strings.Contains(strings.ToLower(message), "password is invalid")) or — better — keying off the structured LINE error code if one is available upstream ofloginErrorReason.