mirror of
https://github.com/PretendoNetwork/friends.git
synced 2026-08-03 16:39:41 -05:00
feat(grpc): add decrypted mii data to 3DS response
This commit is contained in:
parent
067363fd84
commit
ab0f152eb3
|
|
@ -98,4 +98,5 @@ All configuration options are handled via environment variables
|
|||
| `PN_FRIENDS_CONFIG_ACCOUNT_GRPC_PORT` | Port for your account server gRPC service | Yes |
|
||||
| `PN_FRIENDS_CONFIG_ACCOUNT_GRPC_API_KEY` | API key for your account server gRPC service | No (Assumed to be an open gRPC API) |
|
||||
| `PN_FRIENDS_CONFIG_HEALTH_CHECK_PORT` | Port for the basic UDP health check server | No |
|
||||
| `PN_FRIENDS_CONFIG_ENABLE_BELLA` | Enables a debug user named "Bella" which is always assigned as your friend | No | No
|
||||
| `PN_FRIENDS_CONFIG_ENABLE_BELLA` | Enables a debug user named "Bella" which is always assigned as your friend | No |
|
||||
| `PN_FRIENDS_CONFIG_MII_DECRYPT_KEY` | AES key used to decrypt 3DS Mii data (as a hex string) | Yes |
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ type config struct {
|
|||
AccountGRPCAPIKey string `envconf:"optional"`
|
||||
HealthCheckPort uint16 `envconf:"optional"`
|
||||
EnableBella bool `envconf:"optional"`
|
||||
MiiDecryptKey string
|
||||
}
|
||||
|
||||
var Config *config = &config{}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
database_3ds "github.com/PretendoNetwork/friends/database/3ds"
|
||||
database_wiiu "github.com/PretendoNetwork/friends/database/wiiu"
|
||||
"github.com/PretendoNetwork/friends/globals"
|
||||
"github.com/PretendoNetwork/friends/utility"
|
||||
pb "github.com/PretendoNetwork/grpc/go/friends/v2"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
"google.golang.org/grpc/codes"
|
||||
|
|
@ -106,7 +107,11 @@ func (s *gRPCFriendsV2Server) GetUserData3DS(ctx context.Context, in *pb.GetUser
|
|||
ProfanityFlag: bool(miiData.Mii.ProfanityFlag),
|
||||
CharacterSet: uint32(miiData.Mii.CharacterSet),
|
||||
MiiDataEncrypted: miiData.Mii.MiiData,
|
||||
// TODO: Implement MiiData
|
||||
}
|
||||
|
||||
mii_data, err := utility.DecryptMiiData(miiData.Mii.MiiData)
|
||||
if err == nil {
|
||||
mii.MiiData = mii_data
|
||||
}
|
||||
friendMii := &pb.FriendMii{
|
||||
Pid: uint32(miiData.PID),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
database_3ds "github.com/PretendoNetwork/friends/database/3ds"
|
||||
database_wiiu "github.com/PretendoNetwork/friends/database/wiiu"
|
||||
"github.com/PretendoNetwork/friends/globals"
|
||||
"github.com/PretendoNetwork/friends/utility"
|
||||
pb "github.com/PretendoNetwork/grpc/go/friends/v2"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
friends_3ds_types "github.com/PretendoNetwork/nex-protocols-go/v2/friends-3ds/types"
|
||||
|
|
@ -241,10 +242,15 @@ func (s *gRPCFriendsV2Server) GetUserFriendsData3DS(ctx context.Context, in *pb.
|
|||
|
||||
miiData := miiList[miiIndex]
|
||||
mii := &pb.Mii{
|
||||
Name: string(miiData.Mii.Name),
|
||||
ProfanityFlag: bool(miiData.Mii.ProfanityFlag),
|
||||
CharacterSet: uint32(miiData.Mii.CharacterSet),
|
||||
MiiData: miiData.Mii.MiiData,
|
||||
Name: string(miiData.Mii.Name),
|
||||
ProfanityFlag: bool(miiData.Mii.ProfanityFlag),
|
||||
CharacterSet: uint32(miiData.Mii.CharacterSet),
|
||||
MiiDataEncrypted: miiData.Mii.MiiData,
|
||||
}
|
||||
|
||||
mii_data, err := utility.DecryptMiiData(miiData.Mii.MiiData)
|
||||
if err == nil {
|
||||
mii.MiiData = mii_data
|
||||
}
|
||||
|
||||
friendMii := &pb.FriendMii{
|
||||
|
|
|
|||
57
utility/decrypt_mii.go
Normal file
57
utility/decrypt_mii.go
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package utility
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/PretendoNetwork/friends/globals"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
)
|
||||
|
||||
func ccmDecrypt(key, nonce, ciphertext []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
L := 15 - len(nonce)
|
||||
|
||||
counter := make([]byte, aes.BlockSize)
|
||||
counter[0] = byte(L - 1)
|
||||
copy(counter[1:1+len(nonce)], nonce)
|
||||
stream := cipher.NewCTR(block, counter)
|
||||
|
||||
padded := make([]byte, aes.BlockSize+len(ciphertext))
|
||||
copy(padded[aes.BlockSize:], ciphertext)
|
||||
|
||||
out := make([]byte, len(padded))
|
||||
stream.XORKeyStream(out, padded)
|
||||
|
||||
return out[aes.BlockSize:], nil
|
||||
}
|
||||
|
||||
func DecryptMiiData(mii_data types.Buffer) ([]byte, error) {
|
||||
if len(mii_data) < 96 {
|
||||
return nil, fmt.Errorf("Mii data length is incorrect: %d", len(mii_data))
|
||||
}
|
||||
nonce := mii_data[:8]
|
||||
ciphertext := mii_data[8 : 8+0x58]
|
||||
|
||||
key, err := hex.DecodeString(globals.Config.MiiDecryptKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err := ccmDecrypt(key, append(append([]byte{}, nonce...), 0, 0, 0, 0), ciphertext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]byte, 0, len(content)+len(nonce))
|
||||
result = append(result, content[:12]...)
|
||||
result = append(result, nonce...)
|
||||
result = append(result, content[12:]...)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user