0x17, 0x00, 0x20, 0xfd, 0x36, 0x18, 0x75, 0x77, 0x10, 0x57, 0x39, 0xf7, 0xe2, 0x52, 0x92, 0xa3,
0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+
+uint8_t _recipientKeyID_content[] = {
+ 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70,
+ 0x6c, 0x61, 0x69, 0x6e, 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x22, 0x49, 0x53, 0x4f, 0x2d, 0x32,
+ 0x30, 0x32, 0x32, 0x2d, 0x4a, 0x50, 0x22, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x72, 0x61,
+ 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x37, 0x62, 0x69, 0x74,
+ 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x2d, 0x2d, 0x20, 0x0d, 0x0a, 0x1b, 0x24, 0x42, 0x31, 0x4a, 0x30, 0x42, 0x1b, 0x28,
+ 0x42, 0x20, 0x1b, 0x24, 0x42, 0x4d, 0x24, 0x34, 0x75, 0x30, 0x74, 0x1b, 0x28, 0x42, 0x20, 0x28, 0x1b, 0x24, 0x42, 0x24,
+ 0x4a, 0x24, 0x2c, 0x24, 0x64, 0x24, 0x39, 0x1b, 0x28, 0x42, 0x20, 0x1b, 0x24, 0x42, 0x24, 0x66, 0x24, 0x2d, 0x24, 0x4e,
+ 0x24, 0x56, 0x1b, 0x28, 0x42, 0x29, 0x20, 0x3c, 0x6e, 0x61, 0x67, 0x61, 0x79, 0x61, 0x73, 0x75, 0x40, 0x79, 0x75, 0x6b,
+ 0x69, 0x6e, 0x6f, 0x62, 0x75, 0x2e, 0x6a, 0x70, 0x3e, 0x0d, 0x0a
+};
+
+uint8_t _recipientKeyID_cms[] = {
+ 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x82, 0x14, 0x80, 0x02,
+ 0x01, 0x03, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x30,
+ 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x10, 0xfd, 0x30, 0x82, 0x05, 0x33,
+ 0x30, 0x82, 0x04, 0x1b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x43, 0x3d, 0xe2, 0x93, 0xa4, 0xed, 0xf7, 0x8d, 0x8b,
+ 0x98, 0x93, 0x72, 0x76, 0xdd, 0x46, 0xe7, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+ 0x05, 0x00, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b,
+ 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e,
+ 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61,
+ 0x6c, 0x66, 0x6f, 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43, 0x4f, 0x4d, 0x4f,
+ 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x3d, 0x30, 0x3b, 0x06, 0x03, 0x55,
+ 0x04, 0x03, 0x13, 0x34, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e,
+ 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64,
+ 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d,
+ 0x31, 0x38, 0x30, 0x32, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x32,
+ 0x33, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x25, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x6e, 0x61, 0x67, 0x61, 0x79, 0x61, 0x73, 0x75, 0x40, 0x79, 0x75, 0x6b, 0x69,
+ 0x6e, 0x6f, 0x62, 0x75, 0x2e, 0x6a, 0x70, 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,
+ 0xb2, 0x9b, 0x24, 0xac, 0xc7, 0x87, 0xc2, 0x39, 0xf3, 0x11, 0x57, 0x69, 0x29, 0x47, 0x52, 0x38, 0x8c, 0x2a, 0xbc, 0xdd,
+ 0x9e, 0xfd, 0x2e, 0x5f, 0x0c, 0x3b, 0x36, 0x66, 0x30, 0xc0, 0x7f, 0x3f, 0xff, 0xcd, 0x53, 0xfc, 0x04, 0xab, 0x94, 0xb8,
+ 0xfa, 0xa9, 0x65, 0xed, 0xa6, 0x40, 0x34, 0x80, 0x86, 0x61, 0xba, 0x7e, 0x2f, 0xba, 0x37, 0x97, 0x97, 0xf3, 0xe0, 0x16,
+ 0x50, 0x27, 0xf3, 0x52, 0xe9, 0x53, 0x2c, 0x7c, 0x30, 0x43, 0xdf, 0xa4, 0x66, 0x87, 0x26, 0x3a, 0xff, 0x68, 0x62, 0x18,
+ 0xbb, 0x84, 0x6d, 0x64, 0x1e, 0xc5, 0x7c, 0x91, 0xa4, 0x9c, 0xe9, 0x7d, 0x87, 0x8f, 0x22, 0xe8, 0x26, 0xa6, 0x35, 0xc9,
+ 0xf2, 0x61, 0xf6, 0xf3, 0x34, 0xd5, 0x06, 0x61, 0x75, 0x16, 0x57, 0xc5, 0xc9, 0x43, 0xd9, 0xf0, 0xd6, 0x3b, 0xb4, 0x17,
+ 0xe9, 0xc6, 0x34, 0xa1, 0xd7, 0x39, 0x14, 0x36, 0x7f, 0xb3, 0xb9, 0x9f, 0xa4, 0x2b, 0xf2, 0x28, 0xd0, 0x5d, 0xfe, 0x29,
+ 0x49, 0xa2, 0x18, 0x54, 0x80, 0x86, 0x13, 0x4a, 0x33, 0xb0, 0x6e, 0xf9, 0x00, 0x7e, 0x87, 0xd1, 0xc5, 0x13, 0x56, 0x94,
+ 0x78, 0x86, 0x7e, 0x31, 0xf5, 0x5e, 0xc8, 0x9b, 0x41, 0x4f, 0x8a, 0x76, 0x0f, 0xdd, 0xe6, 0xae, 0x08, 0x58, 0xae, 0x8d,
+ 0xd1, 0x2f, 0x3d, 0x06, 0xc5, 0xef, 0xbc, 0xce, 0x38, 0x47, 0xfd, 0x7f, 0x5b, 0x84, 0x31, 0xb1, 0x41, 0x1d, 0xfd, 0x7c,
+ 0x65, 0xc5, 0x0d, 0x82, 0x6a, 0xc1, 0x82, 0x42, 0xc0, 0xdb, 0x21, 0x15, 0x8a, 0x76, 0x69, 0x4a, 0x98, 0x69, 0x85, 0x0c,
+ 0x82, 0x88, 0xb0, 0xf7, 0x8d, 0x91, 0x9a, 0xe8, 0xf8, 0xb0, 0x9a, 0x86, 0xf8, 0x3d, 0x2f, 0xba, 0x16, 0x0f, 0x45, 0x30,
+ 0xb3, 0xfd, 0xf2, 0xd0, 0xb8, 0x86, 0x76, 0x69, 0x83, 0xd8, 0xae, 0x51, 0xdc, 0x71, 0xf3, 0x5d, 0x02, 0x03, 0x01, 0x00,
+ 0x01, 0xa3, 0x82, 0x01, 0xea, 0x30, 0x82, 0x01, 0xe6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
+ 0x80, 0x14, 0x82, 0xaf, 0x6c, 0x8c, 0xf8, 0xc5, 0xfe, 0x96, 0x61, 0x7c, 0xe8, 0x1f, 0x3d, 0x2b, 0x71, 0x48, 0x5e, 0xc4,
+ 0x8b, 0xc0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x31, 0x34, 0xad, 0xb0, 0xf8, 0xc0, 0x87,
+ 0x77, 0xe5, 0x9b, 0x2a, 0xda, 0x75, 0x10, 0x98, 0x65, 0xae, 0xac, 0xfc, 0x84, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f,
+ 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04,
+ 0x02, 0x30, 0x00, 0x30, 0x20, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x19, 0x30, 0x17, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x07, 0x03, 0x04, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x03, 0x05, 0x02, 0x30, 0x11, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x05, 0x20, 0x30, 0x46, 0x06, 0x03,
+ 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02,
+ 0x01, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68,
+ 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f,
+ 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x5a, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x53, 0x30, 0x51, 0x30,
+ 0x4f, 0xa0, 0x4d, 0xa0, 0x4b, 0x86, 0x49, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x52, 0x53, 0x41,
+ 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x61, 0x6e, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c,
+ 0x30, 0x81, 0x8b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x7f, 0x30, 0x7d, 0x30, 0x55, 0x06,
+ 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x49, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+ 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x4f, 0x4d, 0x4f, 0x44,
+ 0x4f, 0x52, 0x53, 0x41, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6e, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x41,
+ 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x18, 0x30, 0x16, 0x81, 0x14, 0x6e, 0x61, 0x67, 0x61, 0x79,
+ 0x61, 0x73, 0x75, 0x40, 0x79, 0x75, 0x6b, 0x69, 0x6e, 0x6f, 0x62, 0x75, 0x2e, 0x6a, 0x70, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb5, 0x1e, 0xd2, 0xd6, 0x87,
+ 0x90, 0x6b, 0x00, 0x9d, 0xed, 0x82, 0x7d, 0xc3, 0x47, 0xbf, 0xb3, 0x7a, 0x0d, 0x3d, 0xf8, 0x6d, 0xb7, 0x7c, 0x4a, 0xd9,
+ 0xb1, 0x4f, 0x1e, 0x10, 0x69, 0x19, 0x39, 0x65, 0x2d, 0x0d, 0x92, 0x0f, 0x5e, 0xf1, 0x0a, 0x66, 0x5a, 0x55, 0x52, 0x96,
+ 0x48, 0x95, 0x4a, 0x4f, 0xf5, 0x12, 0x6c, 0x31, 0x9f, 0x92, 0x71, 0xa8, 0x1d, 0x06, 0x62, 0xe7, 0xed, 0xb0, 0x18, 0x84,
+ 0xdf, 0x60, 0x94, 0xb2, 0x59, 0x05, 0xe5, 0xac, 0xc7, 0xc4, 0xe0, 0xd7, 0xea, 0xfb, 0x53, 0xbe, 0x9c, 0x6a, 0xa6, 0x80,
+ 0x84, 0xc3, 0x2a, 0xb5, 0x20, 0xe6, 0x7d, 0x27, 0x8c, 0xc1, 0x9d, 0x2b, 0xb3, 0x03, 0x68, 0x5a, 0xdb, 0xce, 0xc9, 0xdf,
+ 0x51, 0xc6, 0xf2, 0x5f, 0x1f, 0x8c, 0xb1, 0x4a, 0x32, 0x49, 0x7a, 0x57, 0xee, 0xea, 0xf0, 0x38, 0x6a, 0x48, 0xcc, 0xd0,
+ 0xce, 0x12, 0xf6, 0x71, 0xc0, 0xbe, 0xe0, 0x62, 0x37, 0xc0, 0x92, 0xfa, 0x95, 0xc0, 0x2e, 0x71, 0x05, 0x40, 0x0b, 0xec,
+ 0xe3, 0x0c, 0x72, 0x6c, 0x7a, 0x1a, 0x67, 0xe8, 0x3c, 0xc4, 0x80, 0x44, 0xb0, 0xc5, 0x6d, 0x66, 0x70, 0x15, 0x94, 0xa4,
+ 0x68, 0x34, 0xb1, 0x3d, 0x40, 0xb1, 0x87, 0x98, 0xd0, 0xee, 0x07, 0x98, 0x21, 0xa3, 0x09, 0x97, 0xcf, 0x93, 0x17, 0x3a,
+ 0xd7, 0xb8, 0xa8, 0xaa, 0x18, 0xc9, 0x12, 0xd8, 0x46, 0x04, 0x15, 0xaa, 0xe4, 0xce, 0x39, 0xf2, 0xbd, 0x0c, 0xc6, 0xc7,
+ 0xb7, 0xe4, 0x0e, 0x87, 0xb3, 0x9e, 0x6a, 0xce, 0x7a, 0x35, 0x84, 0xce, 0xbf, 0x7f, 0x2c, 0x93, 0xea, 0x47, 0x98, 0x98,
+ 0xf7, 0xec, 0xdc, 0x4f, 0x31, 0xe7, 0x11, 0x27, 0x4e, 0x4d, 0x7b, 0x04, 0xb2, 0x23, 0xa2, 0xfa, 0x96, 0xa6, 0x90, 0x73,
+ 0x80, 0x06, 0x69, 0x24, 0x1e, 0x49, 0xaf, 0xd0, 0xe3, 0x76, 0x8a, 0x30, 0x82, 0x05, 0xd8, 0x30, 0x82, 0x03, 0xc0, 0xa0,
+ 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x4c, 0xaa, 0xf9, 0xca, 0xdb, 0x63, 0x6f, 0xe0, 0x1f, 0xf7, 0x4e, 0xd8, 0x5b, 0x03,
+ 0x86, 0x9d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00, 0x30, 0x81, 0x85,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
+ 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74,
+ 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x64,
+ 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41,
+ 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43,
+ 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30,
+ 0x31, 0x31, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x38, 0x30, 0x31, 0x31, 0x38, 0x32, 0x33,
+ 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0x85, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47,
+ 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20,
+ 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13,
+ 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43,
+ 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2b, 0x30, 0x29,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+ 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0x91, 0xe8, 0x54, 0x92, 0xd2, 0x0a,
+ 0x56, 0xb1, 0xac, 0x0d, 0x24, 0xdd, 0xc5, 0xcf, 0x44, 0x67, 0x74, 0x99, 0x2b, 0x37, 0xa3, 0x7d, 0x23, 0x70, 0x00, 0x71,
+ 0xbc, 0x53, 0xdf, 0xc4, 0xfa, 0x2a, 0x12, 0x8f, 0x4b, 0x7f, 0x10, 0x56, 0xbd, 0x9f, 0x70, 0x72, 0xb7, 0x61, 0x7f, 0xc9,
+ 0x4b, 0x0f, 0x17, 0xa7, 0x3d, 0xe3, 0xb0, 0x04, 0x61, 0xee, 0xff, 0x11, 0x97, 0xc7, 0xf4, 0x86, 0x3e, 0x0a, 0xfa, 0x3e,
+ 0x5c, 0xf9, 0x93, 0xe6, 0x34, 0x7a, 0xd9, 0x14, 0x6b, 0xe7, 0x9c, 0xb3, 0x85, 0xa0, 0x82, 0x7a, 0x76, 0xaf, 0x71, 0x90,
+ 0xd7, 0xec, 0xfd, 0x0d, 0xfa, 0x9c, 0x6c, 0xfa, 0xdf, 0xb0, 0x82, 0xf4, 0x14, 0x7e, 0xf9, 0xbe, 0xc4, 0xa6, 0x2f, 0x4f,
+ 0x7f, 0x99, 0x7f, 0xb5, 0xfc, 0x67, 0x43, 0x72, 0xbd, 0x0c, 0x00, 0xd6, 0x89, 0xeb, 0x6b, 0x2c, 0xd3, 0xed, 0x8f, 0x98,
+ 0x1c, 0x14, 0xab, 0x7e, 0xe5, 0xe3, 0x6e, 0xfc, 0xd8, 0xa8, 0xe4, 0x92, 0x24, 0xda, 0x43, 0x6b, 0x62, 0xb8, 0x55, 0xfd,
+ 0xea, 0xc1, 0xbc, 0x6c, 0xb6, 0x8b, 0xf3, 0x0e, 0x8d, 0x9a, 0xe4, 0x9b, 0x6c, 0x69, 0x99, 0xf8, 0x78, 0x48, 0x30, 0x45,
+ 0xd5, 0xad, 0xe1, 0x0d, 0x3c, 0x45, 0x60, 0xfc, 0x32, 0x96, 0x51, 0x27, 0xbc, 0x67, 0xc3, 0xca, 0x2e, 0xb6, 0x6b, 0xea,
+ 0x46, 0xc7, 0xc7, 0x20, 0xa0, 0xb1, 0x1f, 0x65, 0xde, 0x48, 0x08, 0xba, 0xa4, 0x4e, 0xa9, 0xf2, 0x83, 0x46, 0x37, 0x84,
+ 0xeb, 0xe8, 0xcc, 0x81, 0x48, 0x43, 0x67, 0x4e, 0x72, 0x2a, 0x9b, 0x5c, 0xbd, 0x4c, 0x1b, 0x28, 0x8a, 0x5c, 0x22, 0x7b,
+ 0xb4, 0xab, 0x98, 0xd9, 0xee, 0xe0, 0x51, 0x83, 0xc3, 0x09, 0x46, 0x4e, 0x6d, 0x3e, 0x99, 0xfa, 0x95, 0x17, 0xda, 0x7c,
+ 0x33, 0x57, 0x41, 0x3c, 0x8d, 0x51, 0xed, 0x0b, 0xb6, 0x5c, 0xaf, 0x2c, 0x63, 0x1a, 0xdf, 0x57, 0xc8, 0x3f, 0xbc, 0xe9,
+ 0x5d, 0xc4, 0x9b, 0xaf, 0x45, 0x99, 0xe2, 0xa3, 0x5a, 0x24, 0xb4, 0xba, 0xa9, 0x56, 0x3d, 0xcf, 0x6f, 0xaa, 0xff, 0x49,
+ 0x58, 0xbe, 0xf0, 0xa8, 0xff, 0xf4, 0xb8, 0xad, 0xe9, 0x37, 0xfb, 0xba, 0xb8, 0xf4, 0x0b, 0x3a, 0xf9, 0xe8, 0x43, 0x42,
+ 0x1e, 0x89, 0xd8, 0x84, 0xcb, 0x13, 0xf1, 0xd9, 0xbb, 0xe1, 0x89, 0x60, 0xb8, 0x8c, 0x28, 0x56, 0xac, 0x14, 0x1d, 0x9c,
+ 0x0a, 0xe7, 0x71, 0xeb, 0xcf, 0x0e, 0xdd, 0x3d, 0xa9, 0x96, 0xa1, 0x48, 0xbd, 0x3c, 0xf7, 0xaf, 0xb5, 0x0d, 0x22, 0x4c,
+ 0xc0, 0x11, 0x81, 0xec, 0x56, 0x3b, 0xf6, 0xd3, 0xa2, 0xe2, 0x5b, 0xb7, 0xb2, 0x04, 0x22, 0x52, 0x95, 0x80, 0x93, 0x69,
+ 0xe8, 0x8e, 0x4c, 0x65, 0xf1, 0x91, 0x03, 0x2d, 0x70, 0x74, 0x02, 0xea, 0x8b, 0x67, 0x15, 0x29, 0x69, 0x52, 0x02, 0xbb,
+ 0xd7, 0xdf, 0x50, 0x6a, 0x55, 0x46, 0xbf, 0xa0, 0xa3, 0x28, 0x61, 0x7f, 0x70, 0xd0, 0xc3, 0xa2, 0xaa, 0x2c, 0x21, 0xaa,
+ 0x47, 0xce, 0x28, 0x9c, 0x06, 0x45, 0x76, 0xbf, 0x82, 0x18, 0x27, 0xb4, 0xd5, 0xae, 0xb4, 0xcb, 0x50, 0xe6, 0x6b, 0xf4,
+ 0x4c, 0x86, 0x71, 0x30, 0xe9, 0xa6, 0xdf, 0x16, 0x86, 0xe0, 0xd8, 0xff, 0x40, 0xdd, 0xfb, 0xd0, 0x42, 0x88, 0x7f, 0xa3,
+ 0x33, 0x3a, 0x2e, 0x5c, 0x1e, 0x41, 0x11, 0x81, 0x63, 0xce, 0x18, 0x71, 0x6b, 0x2b, 0xec, 0xa6, 0x8a, 0xb7, 0x31, 0x5c,
+ 0x3a, 0x6a, 0x47, 0xe0, 0xc3, 0x79, 0x59, 0xd6, 0x20, 0x1a, 0xaf, 0xf2, 0x6a, 0x98, 0xaa, 0x72, 0xbc, 0x57, 0x4a, 0xd2,
+ 0x4b, 0x9d, 0xbb, 0x10, 0xfc, 0xb0, 0x4c, 0x41, 0xe5, 0xed, 0x1d, 0x3d, 0x5e, 0x28, 0x9d, 0x9c, 0xcc, 0xbf, 0xb3, 0x51,
+ 0xda, 0xa7, 0x47, 0xe5, 0x84, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x42, 0x30, 0x40, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xbb, 0xaf, 0x7e, 0x02, 0x3d, 0xfa, 0xa6, 0xf1, 0x3c, 0x84, 0x8e, 0xad, 0xee, 0x38,
+ 0x98, 0xec, 0xd9, 0x32, 0x32, 0xd4, 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,
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x0a,
+ 0xf1, 0xd5, 0x46, 0x84, 0xb7, 0xae, 0x51, 0xbb, 0x6c, 0xb2, 0x4d, 0x41, 0x14, 0x00, 0x93, 0x4c, 0x9c, 0xcb, 0xe5, 0xc0,
+ 0x54, 0xcf, 0xa0, 0x25, 0x8e, 0x02, 0xf9, 0xfd, 0xb0, 0xa2, 0x0d, 0xf5, 0x20, 0x98, 0x3c, 0x13, 0x2d, 0xac, 0x56, 0xa2,
+ 0xb0, 0xd6, 0x7e, 0x11, 0x92, 0xe9, 0x2e, 0xba, 0x9e, 0x2e, 0x9a, 0x72, 0xb1, 0xbd, 0x19, 0x44, 0x6c, 0x61, 0x35, 0xa2,
+ 0x9a, 0xb4, 0x16, 0x12, 0x69, 0x5a, 0x8c, 0xe1, 0xd7, 0x3e, 0xa4, 0x1a, 0xe8, 0x2f, 0x03, 0xf4, 0xae, 0x61, 0x1d, 0x10,
+ 0x1b, 0x2a, 0xa4, 0x8b, 0x7a, 0xc5, 0xfe, 0x05, 0xa6, 0xe1, 0xc0, 0xd6, 0xc8, 0xfe, 0x9e, 0xae, 0x8f, 0x2b, 0xba, 0x3d,
+ 0x99, 0xf8, 0xd8, 0x73, 0x09, 0x58, 0x46, 0x6e, 0xa6, 0x9c, 0xf4, 0xd7, 0x27, 0xd3, 0x95, 0xda, 0x37, 0x83, 0x72, 0x1c,
+ 0xd3, 0x73, 0xe0, 0xa2, 0x47, 0x99, 0x03, 0x38, 0x5d, 0xd5, 0x49, 0x79, 0x00, 0x29, 0x1c, 0xc7, 0xec, 0x9b, 0x20, 0x1c,
+ 0x07, 0x24, 0x69, 0x57, 0x78, 0xb2, 0x39, 0xfc, 0x3a, 0x84, 0xa0, 0xb5, 0x9c, 0x7c, 0x8d, 0xbf, 0x2e, 0x93, 0x62, 0x27,
+ 0xb7, 0x39, 0xda, 0x17, 0x18, 0xae, 0xbd, 0x3c, 0x09, 0x68, 0xff, 0x84, 0x9b, 0x3c, 0xd5, 0xd6, 0x0b, 0x03, 0xe3, 0x57,
+ 0x9e, 0x14, 0xf7, 0xd1, 0xeb, 0x4f, 0xc8, 0xbd, 0x87, 0x23, 0xb7, 0xb6, 0x49, 0x43, 0x79, 0x85, 0x5c, 0xba, 0xeb, 0x92,
+ 0x0b, 0xa1, 0xc6, 0xe8, 0x68, 0xa8, 0x4c, 0x16, 0xb1, 0x1a, 0x99, 0x0a, 0xe8, 0x53, 0x2c, 0x92, 0xbb, 0xa1, 0x09, 0x18,
+ 0x75, 0x0c, 0x65, 0xa8, 0x7b, 0xcb, 0x23, 0xb7, 0x1a, 0xc2, 0x28, 0x85, 0xc3, 0x1b, 0xff, 0xd0, 0x2b, 0x62, 0xef, 0xa4,
+ 0x7b, 0x09, 0x91, 0x98, 0x67, 0x8c, 0x14, 0x01, 0xcd, 0x68, 0x06, 0x6a, 0x63, 0x21, 0x75, 0x03, 0x80, 0x88, 0x8a, 0x6e,
+ 0x81, 0xc6, 0x85, 0xf2, 0xa9, 0xa4, 0x2d, 0xe7, 0xf4, 0xa5, 0x24, 0x10, 0x47, 0x83, 0xca, 0xcd, 0xf4, 0x8d, 0x79, 0x58,
+ 0xb1, 0x06, 0x9b, 0xe7, 0x1a, 0x2a, 0xd9, 0x9d, 0x01, 0xd7, 0x94, 0x7d, 0xed, 0x03, 0x4a, 0xca, 0xf0, 0xdb, 0xe8, 0xa9,
+ 0x01, 0x3e, 0xf5, 0x56, 0x99, 0xc9, 0x1e, 0x8e, 0x49, 0x3d, 0xbb, 0xe5, 0x09, 0xb9, 0xe0, 0x4f, 0x49, 0x92, 0x3d, 0x16,
+ 0x82, 0x40, 0xcc, 0xcc, 0x59, 0xc6, 0xe6, 0x3a, 0xed, 0x12, 0x2e, 0x69, 0x3c, 0x6c, 0x95, 0xb1, 0xfd, 0xaa, 0x1d, 0x7b,
+ 0x7f, 0x86, 0xbe, 0x1e, 0x0e, 0x32, 0x46, 0xfb, 0xfb, 0x13, 0x8f, 0x75, 0x7f, 0x4c, 0x8b, 0x4b, 0x46, 0x63, 0xfe, 0x00,
+ 0x34, 0x40, 0x70, 0xc1, 0xc3, 0xb9, 0xa1, 0xdd, 0xa6, 0x70, 0xe2, 0x04, 0xb3, 0x41, 0xbc, 0xe9, 0x80, 0x91, 0xea, 0x64,
+ 0x9c, 0x7a, 0xe1, 0x22, 0x03, 0xa9, 0x9c, 0x6e, 0x6f, 0x0e, 0x65, 0x4f, 0x6c, 0x87, 0x87, 0x5e, 0xf3, 0x6e, 0xa0, 0xf9,
+ 0x75, 0xa5, 0x9b, 0x40, 0xe8, 0x53, 0xb2, 0x27, 0x9d, 0x4a, 0xb9, 0xc0, 0x77, 0x21, 0x8d, 0xff, 0x87, 0xf2, 0xde, 0xbc,
+ 0x8c, 0xef, 0x17, 0xdf, 0xb7, 0x49, 0x0b, 0xd1, 0xf2, 0x6e, 0x30, 0x0b, 0x1a, 0x0e, 0x4e, 0x76, 0xed, 0x11, 0xfc, 0xf5,
+ 0xe9, 0x56, 0xb2, 0x7d, 0xbf, 0xc7, 0x6d, 0x0a, 0x93, 0x8c, 0xa5, 0xd0, 0xc0, 0xb6, 0x1d, 0xbe, 0x3a, 0x4e, 0x94, 0xa2,
+ 0xd7, 0x6e, 0x6c, 0x0b, 0xc2, 0x8a, 0x7c, 0xfa, 0x20, 0xf3, 0xc4, 0xe4, 0xe5, 0xcd, 0x0d, 0xa8, 0xcb, 0x91, 0x92, 0xb1,
+ 0x7c, 0x85, 0xec, 0xb5, 0x14, 0x69, 0x66, 0x0e, 0x82, 0xe7, 0xcd, 0xce, 0xc8, 0x2d, 0xa6, 0x51, 0x7f, 0x21, 0xc1, 0x35,
+ 0x53, 0x85, 0x06, 0x4a, 0x5d, 0x9f, 0xad, 0xbb, 0x1b, 0x5f, 0x74, 0x30, 0x82, 0x05, 0xe6, 0x30, 0x82, 0x03, 0xce, 0xa0,
+ 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x6a, 0x9b, 0xe1, 0x38, 0x3b, 0xff, 0x2b, 0x6b, 0x9f, 0x01, 0xd5, 0xd9, 0xb8, 0xa7,
+ 0x52, 0x56, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00, 0x30, 0x81, 0x85,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
+ 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74,
+ 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x64,
+ 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41,
+ 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x43,
+ 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30,
+ 0x31, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x31, 0x30, 0x39, 0x32, 0x33,
+ 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47,
+ 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20,
+ 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13,
+ 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43,
+ 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x3d, 0x30, 0x3b,
+ 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x34, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x6c,
+ 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+ 0x61, 0x6e, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c, 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, 0xbe, 0xb3, 0x9e, 0x57, 0xac, 0x28, 0x76, 0x75,
+ 0x40, 0x16, 0xc7, 0x38, 0x03, 0x98, 0xd3, 0xc6, 0x18, 0x76, 0x21, 0x50, 0xf3, 0x25, 0x79, 0x0b, 0x4c, 0xb5, 0xa0, 0xd1,
+ 0x7d, 0x3a, 0x58, 0x3e, 0x9c, 0xa7, 0x31, 0x2e, 0xa7, 0xf6, 0x34, 0x76, 0xd9, 0x84, 0x6a, 0xda, 0xd0, 0x3d, 0x34, 0x48,
+ 0xe4, 0xea, 0xf5, 0xbb, 0xac, 0xdf, 0xf9, 0xb1, 0x81, 0x4b, 0x20, 0xfd, 0x68, 0x7f, 0x79, 0x74, 0x34, 0xa6, 0x7a, 0x7c,
+ 0xb5, 0x9f, 0x17, 0x65, 0x60, 0x27, 0x97, 0x22, 0x8c, 0xa6, 0x32, 0xfe, 0xa9, 0x40, 0x72, 0x46, 0x35, 0xc2, 0x03, 0xa4,
+ 0x50, 0xc8, 0x33, 0x2a, 0x55, 0xa5, 0x54, 0x91, 0xb2, 0x2b, 0xe5, 0x25, 0x34, 0x44, 0x35, 0xff, 0x91, 0x2b, 0x0a, 0xc1,
+ 0xea, 0xf7, 0x1f, 0x5a, 0x53, 0xfc, 0x75, 0x2b, 0x04, 0xdd, 0x17, 0xf2, 0xc2, 0xad, 0x3d, 0x37, 0x46, 0x5f, 0xc5, 0xc0,
+ 0x5a, 0xdf, 0xd5, 0x74, 0xc2, 0xc1, 0xad, 0x90, 0x65, 0x82, 0xf9, 0xe4, 0x0a, 0x8b, 0x3e, 0x29, 0x05, 0x96, 0x0a, 0x8e,
+ 0xb7, 0x39, 0x34, 0xea, 0x46, 0xf6, 0xaa, 0xf1, 0xa5, 0x9c, 0x72, 0x6f, 0x8a, 0x38, 0xc8, 0xd3, 0x70, 0x4e, 0xac, 0xda,
+ 0x68, 0xfa, 0x46, 0x46, 0xa5, 0xc1, 0xec, 0x83, 0x23, 0xb5, 0xfe, 0xed, 0x4e, 0x65, 0x36, 0x8e, 0xa3, 0xcc, 0x2f, 0x11,
+ 0x4d, 0x7b, 0x55, 0x57, 0x8f, 0xd5, 0xc1, 0xd6, 0xb1, 0xef, 0x6d, 0x18, 0xa4, 0xc3, 0xc9, 0x41, 0xa0, 0xda, 0x12, 0x59,
+ 0x8e, 0xba, 0x9c, 0x93, 0x7f, 0x54, 0x22, 0x6f, 0xe7, 0x29, 0xba, 0x43, 0x49, 0x9d, 0x09, 0xb0, 0xca, 0x08, 0xc3, 0xf2,
+ 0x6d, 0x38, 0xe8, 0x34, 0x24, 0x2e, 0x7a, 0x57, 0x34, 0x20, 0x06, 0x8e, 0xe2, 0x72, 0xd4, 0x5e, 0x4d, 0x01, 0x39, 0x2c,
+ 0x52, 0xc6, 0xdf, 0x24, 0x0a, 0xfb, 0x14, 0xb5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3c, 0x30, 0x82, 0x01,
+ 0x38, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbb, 0xaf, 0x7e, 0x02, 0x3d, 0xfa,
+ 0xa6, 0xf1, 0x3c, 0x84, 0x8e, 0xad, 0xee, 0x38, 0x98, 0xec, 0xd9, 0x32, 0x32, 0xd4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+ 0x0e, 0x04, 0x16, 0x04, 0x14, 0x82, 0xaf, 0x6c, 0x8c, 0xf8, 0xc5, 0xfe, 0x96, 0x61, 0x7c, 0xe8, 0x1f, 0x3d, 0x2b, 0x71,
+ 0x48, 0x5e, 0xc4, 0x8b, 0xc0, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01,
+ 0x86, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01,
+ 0x00, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00,
+ 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0xa0, 0x3f, 0xa0, 0x3d, 0x86, 0x3b, 0x68,
+ 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x2f, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x52, 0x53, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x71,
+ 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x65, 0x30, 0x63, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63,
+ 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x52, 0x53,
+ 0x41, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b,
+ 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x78, 0x5c, 0xb2, 0x81, 0x28, 0x34, 0x4f,
+ 0x3c, 0xee, 0x5f, 0x56, 0xce, 0x9f, 0x97, 0x56, 0xec, 0x8f, 0xa2, 0x6b, 0x17, 0xf6, 0xf3, 0xf6, 0x49, 0x08, 0x06, 0xd4,
+ 0xd8, 0x2f, 0x35, 0xcd, 0xdf, 0x40, 0xfe, 0xd3, 0x71, 0xe3, 0xe8, 0xec, 0x42, 0x0c, 0x11, 0x1a, 0x21, 0xe3, 0x66, 0xb0,
+ 0x18, 0x6b, 0x26, 0x6b, 0xae, 0x6e, 0xfc, 0x84, 0xec, 0x7b, 0x68, 0x4a, 0x64, 0x7c, 0xd3, 0xd0, 0x20, 0x71, 0x86, 0xe8,
+ 0x5b, 0xea, 0xdc, 0x4c, 0xd6, 0x7f, 0xf2, 0xef, 0xc7, 0xbf, 0xe1, 0x93, 0xac, 0xd2, 0x3f, 0x02, 0x1a, 0x97, 0xdb, 0xf9,
+ 0x22, 0x40, 0xdc, 0x66, 0x81, 0x43, 0xed, 0xfd, 0xe2, 0x4f, 0xb3, 0xdd, 0x90, 0x72, 0x58, 0xf4, 0x1e, 0x75, 0x72, 0xcb,
+ 0xd4, 0xe7, 0x4a, 0xf1, 0xa4, 0x48, 0x35, 0x3b, 0x23, 0x93, 0xf1, 0xf9, 0x36, 0xce, 0xfb, 0xcf, 0x06, 0xe3, 0x38, 0xa9,
+ 0x03, 0x6a, 0x6c, 0x65, 0xa5, 0x9e, 0x13, 0x29, 0x20, 0xcc, 0x29, 0x59, 0x94, 0xfc, 0xf5, 0x16, 0x34, 0xc2, 0x92, 0x4e,
+ 0xfb, 0x65, 0x7a, 0x79, 0x71, 0x06, 0x18, 0x7b, 0x11, 0x3a, 0xcd, 0xe7, 0x8d, 0xe3, 0xfd, 0x0e, 0xaa, 0xaa, 0x00, 0x96,
+ 0x81, 0x6b, 0x8c, 0x01, 0x78, 0xa3, 0x9d, 0x18, 0x25, 0xa7, 0xd7, 0xf2, 0x69, 0xda, 0x86, 0x3a, 0x77, 0x23, 0x66, 0x36,
+ 0x9a, 0x48, 0xe1, 0x93, 0x4c, 0x50, 0x7e, 0x13, 0x6a, 0x6f, 0x39, 0x4b, 0x58, 0xfa, 0x13, 0xde, 0x6e, 0xe3, 0xed, 0x4d,
+ 0xba, 0xbb, 0xbc, 0xe0, 0xea, 0xcc, 0x23, 0x3a, 0xaf, 0x21, 0x21, 0x36, 0x1c, 0xdf, 0xf9, 0xe9, 0xe6, 0xd3, 0x39, 0x69,
+ 0x5c, 0xae, 0xea, 0xdf, 0x7d, 0xa7, 0x5e, 0xdb, 0x4d, 0xb6, 0x3b, 0xfb, 0x54, 0x53, 0x58, 0x1b, 0xe2, 0x37, 0xd6, 0x09,
+ 0xcc, 0xaf, 0x07, 0xc7, 0x33, 0x9b, 0x5d, 0x85, 0x81, 0x7f, 0xf2, 0xfe, 0x54, 0x63, 0x98, 0x36, 0xc4, 0x03, 0x4f, 0x10,
+ 0x24, 0xd0, 0x76, 0xef, 0x6f, 0x58, 0xfa, 0x2a, 0x35, 0x21, 0x83, 0xb7, 0xce, 0xdb, 0xde, 0x05, 0xdb, 0xd4, 0x08, 0x86,
+ 0x19, 0xa2, 0x34, 0xea, 0xfc, 0xe0, 0x91, 0xe8, 0xcb, 0xe7, 0xcd, 0x2e, 0x97, 0xef, 0x61, 0xcf, 0xd0, 0xf4, 0x4b, 0x45,
+ 0x38, 0x8e, 0x48, 0x49, 0x88, 0x0e, 0xc4, 0xb9, 0x37, 0x9c, 0x3f, 0xf0, 0x85, 0xb5, 0x1e, 0xf6, 0xb9, 0x84, 0x41, 0x72,
+ 0xe9, 0xf0, 0xc0, 0x7d, 0xdf, 0x72, 0x23, 0xe3, 0xbe, 0x20, 0xc3, 0x00, 0x8f, 0x52, 0x9c, 0x2f, 0xf6, 0x68, 0xf6, 0x3c,
+ 0xc9, 0xd7, 0xa1, 0xce, 0xe6, 0x6e, 0xb4, 0xb6, 0xd9, 0x75, 0x12, 0x79, 0x3c, 0x31, 0x09, 0x33, 0xfd, 0x6d, 0xc9, 0x94,
+ 0x76, 0x9e, 0x23, 0x98, 0x8a, 0x16, 0x7e, 0x14, 0x26, 0xed, 0x7f, 0x70, 0xfd, 0x98, 0x1d, 0x76, 0x0f, 0x89, 0x67, 0xf6,
+ 0x27, 0x20, 0x73, 0xb0, 0xb0, 0x6b, 0x1a, 0x4d, 0x48, 0x23, 0xed, 0xf2, 0x2f, 0xc6, 0xa8, 0xad, 0x87, 0xb0, 0xe8, 0x24,
+ 0x2f, 0x75, 0x58, 0x9f, 0x0b, 0x71, 0xed, 0xc2, 0x54, 0x9a, 0x9b, 0xd5, 0x75, 0x9e, 0x28, 0x82, 0x7c, 0xe0, 0x5e, 0xd8,
+ 0x2d, 0x76, 0x4d, 0xd2, 0x86, 0xbb, 0x4e, 0x4b, 0x58, 0x80, 0x37, 0x66, 0x41, 0x5c, 0x58, 0x91, 0x9a, 0x35, 0x73, 0x99,
+ 0xe8, 0x68, 0x32, 0x87, 0xf4, 0xea, 0xbd, 0x71, 0xb9, 0xbf, 0xbc, 0xe6, 0x11, 0x50, 0xcd, 0x5c, 0x59, 0xc7, 0x9f, 0xdb,
+ 0x45, 0xa4, 0xca, 0x4e, 0x52, 0xfc, 0x61, 0x72, 0xc8, 0xf2, 0x70, 0x1b, 0x47, 0xd1, 0xd6, 0x74, 0x5a, 0xb3, 0x70, 0xea,
+ 0x01, 0xfe, 0x1c, 0x5f, 0x13, 0x22, 0x10, 0xa7, 0x1f, 0x7f, 0xb3, 0xcd, 0x6b, 0x83, 0x37, 0x44, 0x64, 0xea, 0x1f, 0x4a,
+ 0x56, 0x47, 0xca, 0x7a, 0x12, 0x31, 0x82, 0x03, 0x5a, 0x30, 0x82, 0x03, 0x56, 0x02, 0x01, 0x01, 0x30, 0x81, 0xac, 0x30,
+ 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06,
+ 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65,
+ 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f,
+ 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20,
+ 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x3d, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+ 0x34, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41,
+ 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x53, 0x65,
+ 0x63, 0x75, 0x72, 0x65, 0x20, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x20, 0x43, 0x41, 0x02, 0x10, 0x43, 0x3d, 0xe2, 0x93, 0xa4,
+ 0xed, 0xf7, 0x8d, 0x8b, 0x98, 0x93, 0x72, 0x76, 0xdd, 0x46, 0xe7, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
+ 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa0, 0x82, 0x01, 0x7e, 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, 0x31, 0x38, 0x30, 0x33, 0x30, 0x31, 0x31,
+ 0x32, 0x33, 0x33, 0x32, 0x33, 0x5a, 0x30, 0x27, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02,
+ 0x0b, 0x31, 0x18, 0xa1, 0x16, 0x04, 0x14, 0x31, 0x34, 0xad, 0xb0, 0xf8, 0xc0, 0x87, 0x77, 0xe5, 0x9b, 0x2a, 0xda, 0x75,
+ 0x10, 0x98, 0x65, 0xae, 0xac, 0xfc, 0x84, 0x30, 0x3f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04,
+ 0x31, 0x32, 0x04, 0x30, 0xe4, 0xea, 0x14, 0xe1, 0x6d, 0x9c, 0xf0, 0x0e, 0xf6, 0x14, 0x3c, 0xb5, 0x7e, 0x13, 0x05, 0x33,
+ 0x7b, 0x64, 0xb5, 0xa6, 0x15, 0x4e, 0x06, 0x16, 0x7c, 0x69, 0x46, 0x93, 0xc9, 0xf9, 0x3d, 0x83, 0xc0, 0xe3, 0x54, 0x97,
+ 0xb3, 0x4d, 0x97, 0x7f, 0xfa, 0xd6, 0x3a, 0x3c, 0x0c, 0xf5, 0xfa, 0xa9, 0x30, 0x81, 0xd9, 0x06, 0x09, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x31, 0x81, 0xcb, 0x30, 0x81, 0xc8, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+ 0x65, 0x03, 0x04, 0x01, 0x2a, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16, 0x30, 0x0b,
+ 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
+ 0x0d, 0x03, 0x07, 0x30, 0x16, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x08, 0x30, 0x0a, 0x02, 0x01, 0x10,
+ 0x02, 0x02, 0x00, 0xff, 0x02, 0x01, 0x40, 0x30, 0x15, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x08, 0x30,
+ 0x09, 0x02, 0x01, 0x10, 0x02, 0x01, 0x10, 0x02, 0x01, 0x40, 0x30, 0x0e, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x03, 0x02, 0x02, 0x02, 0x00, 0x80, 0x30, 0x16, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x08, 0x30, 0x0a,
+ 0x02, 0x01, 0x08, 0x02, 0x02, 0x00, 0xff, 0x02, 0x01, 0x40, 0x30, 0x15, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x03, 0x08, 0x30, 0x09, 0x02, 0x01, 0x08, 0x02, 0x01, 0x10, 0x02, 0x01, 0x40, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48,
+ 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x40, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02,
+ 0x02, 0x01, 0x28, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x21, 0x05, 0x42, 0x5d, 0x88, 0x06, 0x2c, 0xf5, 0x83,
+ 0xe8, 0xbe, 0x16, 0x66, 0x90, 0x37, 0xa6, 0x6a, 0x73, 0xa9, 0x78, 0xc8, 0x0d, 0xe4, 0xfe, 0xfc, 0xa2, 0x79, 0xdd, 0x9b,
+ 0xf3, 0xef, 0x19, 0x2f, 0x4a, 0x9a, 0x46, 0xf8, 0x13, 0x7f, 0x77, 0xa5, 0x67, 0x2e, 0xf1, 0x0c, 0xff, 0x25, 0x9e, 0xfd,
+ 0x68, 0x02, 0x61, 0x53, 0x7c, 0x4d, 0xa4, 0xa6, 0x14, 0x43, 0x70, 0x29, 0xc2, 0x5b, 0xe7, 0x7a, 0xcd, 0xe8, 0x78, 0xa3,
+ 0xd5, 0x36, 0x21, 0x50, 0xf6, 0xb1, 0xcc, 0xfc, 0x18, 0xd4, 0x8a, 0x7b, 0x19, 0x6e, 0x5c, 0x19, 0xe2, 0xb2, 0xc3, 0x82,
+ 0x3f, 0x77, 0x8f, 0x70, 0x6b, 0xf4, 0x21, 0x81, 0x05, 0x96, 0xd9, 0xa3, 0xa4, 0xb6, 0xe0, 0x22, 0x48, 0x9d, 0xb4, 0x39,
+ 0x03, 0x4b, 0xa2, 0x1a, 0xe4, 0x40, 0x8a, 0x7d, 0xfe, 0x42, 0xca, 0x20, 0x7e, 0xca, 0x88, 0xb5, 0x4a, 0x82, 0x9b, 0x1b,
+ 0x40, 0x0f, 0x35, 0xdf, 0x52, 0x7d, 0x64, 0xfb, 0xab, 0x60, 0x11, 0xfc, 0x38, 0x84, 0xbd, 0xd8, 0xe1, 0x06, 0xdb, 0x2e,
+ 0x8d, 0x03, 0x4c, 0x8a, 0x93, 0xde, 0x37, 0xf5, 0xc0, 0x16, 0x57, 0x13, 0x47, 0x06, 0x6d, 0xd0, 0x70, 0xd1, 0x57, 0x5b,
+ 0xbd, 0x4d, 0xe2, 0xca, 0x01, 0xef, 0x61, 0xbf, 0xc6, 0x4b, 0x30, 0x92, 0x8b, 0x58, 0xb8, 0xe4, 0xf6, 0x42, 0xb4, 0x37,
+ 0xda, 0xe6, 0x76, 0xe0, 0xcf, 0xf8, 0xec, 0xeb, 0x96, 0x9e, 0x04, 0x39, 0x17, 0x32, 0xf6, 0x0b, 0xe7, 0x8b, 0x62, 0xa6,
+ 0x31, 0x42, 0xa6, 0x3d, 0xb0, 0x37, 0x98, 0x52, 0xe2, 0x59, 0xa1, 0x48, 0x58, 0x75, 0x23, 0x35, 0x84, 0x88, 0x08, 0xe6,
+ 0xea, 0xca, 0x28, 0x8e, 0x14, 0x98, 0xe8, 0x68, 0x43, 0x9f, 0x23, 0xd1, 0x22, 0x44, 0x95, 0xd8, 0x34, 0x3a, 0xaa, 0x4a,
+ 0x01, 0xb7, 0xe5, 0x10, 0x98, 0x22, 0x7c, 0x00, 0x00, 0x00, 0x00
+};
#import <securityd/SecTrustLoggingServer.h>
#endif
+#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
+#import <MobileKeyBag/MobileKeyBag.h>
+#endif
+
#if TARGET_OS_OSX
#import <MobileAsset/MobileAsset.h>
#endif
return nsType && [nsType isKindOfClass:[NSArray class]];
}
+static inline bool isNSDate(id nsType) {
+ return nsType && [nsType isKindOfClass:[NSDate class]];
+}
+
#define SECURITYD_ROLE_ACCOUNT 64
#define ROOT_ACCOUNT 0
/* MARK: - */
/* MARK: MobileAsset Updates */
// MARK: Forward Declarations
-static uint64_t GetAssetVersion(void);
+static uint64_t GetAssetVersion(CFErrorRef *error);
+static uint64_t GetSystemVersion(CFStringRef key);
#if !TARGET_OS_BRIDGE
-static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version);
+static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version, NSError **error);
static BOOL UpdateOTACheckInDate(void);
#endif
+#if TARGET_OS_IPHONE
+static void TriggerUnlockNotificationOTATrustAssetCheck(dispatch_queue_t queue);
+#endif
+
+/* This queue is for fetching changes to the OTAPKI reference or otherwise doing maintenance activities */
+static dispatch_queue_t kOTABackgroundQueue = NULL;
// MARK: Constants
NSString *kOTATrustContentVersionKey = @"MobileAssetContentVersion";
// MARK: Helper functions
typedef enum {
+ OTATrustLogLevelNone,
OTATrustLogLevelDebug,
OTATrustLogLevelInfo,
OTATrustLogLevelNotice,
} OTATrustLogLevel;
static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(5,6);
+static void MakeOTATrustErrorWithAttributes(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode,
+ NSDictionary *attributes, NSString *format,...)
+ NS_FORMAT_FUNCTION(6,7);
+
+static void MakeOTATrustErrorArgs(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode,
+ NSDictionary *attributes, NSString *format, va_list arguments)
+ NS_FORMAT_FUNCTION(6,0);
static void LogLocally(OTATrustLogLevel level, NSString *errorString) {
switch (level) {
+ case OTATrustLogLevelNone:
+ break;
case OTATrustLogLevelDebug:
secdebug("OTATrust", "%@", errorString);
break;
}
}
-static void LogRemotely(OTATrustLogLevel level, NSError **error) {
+static void LogRemotelyWithAttributes(OTATrustLogLevel level, NSError **error, NSDictionary *attributes) {
#if ENABLE_TRUSTD_ANALYTICS
/* only report errors and notices */
if (error && level == OTATrustLogLevelError) {
- [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventOTAPKIEvent hardFailure:YES result:*error];
+ [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventOTAPKIEvent hardFailure:YES result:*error withAttributes:attributes];
} else if (error && level == OTATrustLogLevelNotice) {
- [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventOTAPKIEvent hardFailure:NO result:*error];
+ [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventOTAPKIEvent hardFailure:NO result:*error withAttributes:attributes];
}
#endif // ENABLE_TRUSTD_ANALYTICS
}
-static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) {
- va_list args;
- va_start(args, format);
+static void LogRemotely(OTATrustLogLevel level, NSError **error) {
+ LogRemotelyWithAttributes(level, error, nil);
+}
+
+static void MakeOTATrustErrorArgs(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode,
+ NSDictionary *attributes, NSString *format, va_list args) {
NSString *formattedString = nil;
if (format) {
formattedString = [[NSString alloc] initWithFormat:format arguments:args];
if (format) {
[userInfo setObject:formattedString forKey:NSLocalizedDescriptionKey];
}
+ if (error && *error) {
+ userInfo[NSUnderlyingErrorKey] = *error;
+ }
localError = [NSError errorWithDomain:errDomain
code:errCode
userInfo:userInfo];
LogLocally(level, formattedString);
- LogRemotely(level, &localError);
+ LogRemotelyWithAttributes(level, &localError, attributes);
if (error) { *error = localError; }
+}
+
+static void MakeOTATrustErrorWithAttributes(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode,
+ NSDictionary *attributes, NSString *format,...) {
+ va_list args;
+ va_start(args, format);
+ MakeOTATrustErrorArgs(error, level, errDomain, errCode, attributes, format, args);
+ va_end(args);
+}
+
+static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) {
+ va_list args;
+ va_start(args, format);
+ MakeOTATrustErrorArgs(error, level, errDomain, errCode, nil, format, args);
va_end(args);
}
}
}
-static void DeleteAssetFromDisk(void) {
- if (SecOTAPKIIsSystemTrustd()) {
- DeleteFileWithName(kOTATrustContextFilename);
- DeleteFileWithName(kOTATrustTrustedCTLogsFilename);
- DeleteFileWithName(kOTATrustAnalyticsSamplingRatesFilename);
- DeleteFileWithName(kOTATrustAppleCertifcateAuthoritiesFilename);
- }
-}
-
-static BOOL UpdateOTAContextOnDisk(NSString *key, id value) {
+static BOOL UpdateOTAContextOnDisk(NSString *key, id value, NSError **error) {
if (SecOTAPKIIsSystemTrustd()) {
/* Get current context, if applicable, and update/add key/value */
NSURL *otaContextFile = GetAssetFileURL(kOTATrustContextFilename);
newContext[key] = value;
/* Write dictionary to disk */
- NSError *error = nil;
- [newContext writeToURL:otaContextFile error:&error];
- if (error) {
- secerror("OTATrust: unable to write asset version to disk: %@", error);
- LogRemotely(OTATrustLogLevelError, &error);
+ if (![newContext writeToURL:otaContextFile error:error]) {
+ secerror("OTATrust: unable to write OTA Context to disk: %@", error ? *error : nil);
+ LogRemotely(OTATrustLogLevelError, error);
return NO;
}
return YES;
return NO;
}
-static BOOL CopyFileToDisk(NSString *filename, NSURL *localURL) {
+static BOOL UpdateOTAContext(NSNumber *asset_version, NSError **error) {
+ return UpdateOTAContextOnDisk(kOTATrustContentVersionKey, asset_version, error) && UpdateOTACheckInDate();
+}
+
+/* Delete only the asset data but not the check-in time. */
+static void DeleteOldAssetData(void) {
+ if (SecOTAPKIIsSystemTrustd()) {
+ /* Delete the asset files, but keep the check-in time and version */
+ DeleteFileWithName(kOTATrustTrustedCTLogsFilename);
+ DeleteFileWithName(kOTATrustAnalyticsSamplingRatesFilename);
+ DeleteFileWithName(kOTATrustAppleCertifcateAuthoritiesFilename);
+ }
+}
+
+/* Delete all asset data, intended for error cases */
+static BOOL DeleteAssetFromDisk(void) {
+ if (SecOTAPKIIsSystemTrustd()) {
+ DeleteOldAssetData();
+ DeleteFileWithName(kOTATrustContextFilename);
+ return YES;
+ }
+ return NO;
+}
+
+static BOOL CopyFileToDisk(NSString *filename, NSURL *localURL, NSError **error) {
if (SecOTAPKIIsSystemTrustd()) {
NSURL *toFileURL = GetAssetFileURL(filename);
secdebug("OTATrust", "will copy asset file data from \"%@\"", localURL);
state, COPYFILE_DATA);
copyfile_state_free(state);
if (retval < 0) {
- secerror("OTATrust: copyfile error for asset %d", retval);
+ MakeOTATrustError(error, OTATrustLogLevelError, NSPOSIXErrorDomain, errno,
+ @"copyfile error for asset %d: %s", errno, strerror(errno));
return NO;
} else {
return YES;
// MARK: Fetch and Update Functions
#if TARGET_OS_IPHONE
static NSNumber *UpdateAndPurgeAsset(MAAsset *asset, NSNumber *asset_version, NSError **error) {
- if (SecPinningDbUpdateFromURL((__bridge CFURLRef)[asset getLocalFileUrl]) &&
- UpdateFromAsset([asset getLocalFileUrl], asset_version)) {
+ if (SecPinningDbUpdateFromURL([asset getLocalFileUrl], error) &&
+ UpdateFromAsset([asset getLocalFileUrl], asset_version, error)) {
secnotice("OTATrust", "finished update to version %@ from installed asset. purging asset.", asset_version);
#if ENABLE_TRUSTD_ANALYTICS
[[TrustdHealthAnalytics logger] logSuccessForEventNamed:TrustdHealthAnalyticsEventOTAPKIEvent];
}
}
+static MADownloadOptions *GetMADownloadOptions(BOOL wait) {
+ /* default behavior */
+ MADownloadOptions *options = [[MADownloadOptions alloc] init];
+ options.discretionary = YES;
+ options.allowsCellularAccess = NO;
+
+ /* If an XPC interface is waiting on this, all expenses allowed */
+ if (wait) {
+ options.discretionary = NO;
+ options.allowsCellularAccess = YES;
+ return options;
+ }
+
+ /* If last asset check-in was too long ago, use more expensive options */
+ SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+ if (!SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessWarning)) {
+ secnotice("OTATrust", "Asset staleness state: warning");
+ options.allowsCellularAccess = YES;
+ options.discretionary = NO;
+ } else if (!SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessAtRisk)) {
+ secnotice("OTATrust", "Asset staleness state: at risk");
+ options.discretionary = NO;
+ }
+ CFReleaseNull(otapkiref);
+ return options;
+}
+
static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) {
if (!CanCheckMobileAsset()) {
MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable,
__block dispatch_semaphore_t done = wait ? dispatch_semaphore_create(0) : nil;
__block NSError *ma_error = nil;
secnotice("OTATrust", "begin MobileAsset query for catalog");
- [MAAsset startCatalogDownload:(NSString *)OTATrustMobileAssetType then:^(MADownLoadResult result) {
+ [MAAsset startCatalogDownload:(NSString *)OTATrustMobileAssetType options:GetMADownloadOptions(wait) then:^(MADownLoadResult result) {
@autoreleasepool {
os_transaction_t transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.download");
if (result != MADownloadSucceesful) {
MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", result,
@"failed to download catalog: %ld", (long)result);
+ if (result == MADownloadDaemonNotReady) {
+ /* mobileassetd has to wait for first unlock to downalod. trustd usually launches before first unlock. */
+ TriggerUnlockNotificationOTATrustAssetCheck(kOTABackgroundQueue);
+ }
return;
}
MAAssetQuery *query = [[MAAssetQuery alloc] initWithType:(NSString *)OTATrustMobileAssetType];
continue;
}
- /* We got an Asset that this device could use; write the last check-in time as now. */
- (void)UpdateOTACheckInDate();
-
/* Check Content Version against the current content version */
NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"];
if (!ShouldUpdateWithAsset(asset_version)) {
- MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem,
- @"skipping asset because we already have _ContentVersion %@ (or newer)", asset_version);
+ /* write the version and last (successful) check-in time */
+ UpdateOTAContext(asset_version, &ma_error);
+ NSDictionary *eventAttributes = @{
+ @"assetVersion" : asset_version,
+ @"systemVersion" : @(GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey)),
+ @"installedVersion" : @(SecOTAPKIGetCurrentAssetVersion(nil)),
+ };
+ MakeOTATrustErrorWithAttributes(&ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, eventAttributes,
+ @"skipping asset because we already have _ContentVersion %@ (or newer)", asset_version);
continue;
}
case MANotPresent:
secnotice("OTATrust", "begin download of OTATrust asset");
began_async_job = true;
- [asset startDownload:^(MADownLoadResult downloadResult) {
+ [asset startDownload:GetMADownloadOptions(wait) then:^(MADownLoadResult downloadResult) {
@autoreleasepool {
os_transaction_t inner_transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.downloadAsset");
if (downloadResult != MADownloadSucceesful) {
}
return result;
}
+
+static void TriggerUnlockNotificationOTATrustAssetCheck(dispatch_queue_t queue) {
+ SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+ /* If the last check-in is recent enough, wait for our regularly scheduled check-in. */
+ if (SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessAtRisk)) {
+ CFReleaseNull(otapkiref);
+ return;
+ }
+#if !TARGET_OS_SIMULATOR
+ /* register for unlock notifications */
+ int out_token = 0;
+ notify_register_dispatch(kMobileKeyBagLockStatusNotificationID, &out_token, queue, ^(int token) {
+ secnotice("OTATrust", "Got lock status notification for at-risk last check-in after MA daemon error");
+ (void)DownloadOTATrustAsset(NO, NO, nil);
+ notify_cancel(token);
+ });
+#endif
+}
#else /* !TARGET_OS_IPHONE */
/* <rdar://problem/30879827> MobileAssetV2 fails on macOS, so use V1 */
static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NSError **error) {
- if (SecPinningDbUpdateFromURL((__bridge CFURLRef)[asset localURL]) &&
- UpdateFromAsset([asset localURL], asset_version)) {
+ if (SecPinningDbUpdateFromURL([asset localURL], error) &&
+ UpdateFromAsset([asset localURL], asset_version, error)) {
secnotice("OTATrust", "finished update to version %@ from installed asset. purging asset.", asset_version);
#if ENABLE_TRUSTD_ANALYTICS
[[TrustdHealthAnalytics logger] logSuccessForEventNamed:TrustdHealthAnalyticsEventOTAPKIEvent];
}
}
+static NSDictionary *GetASDownloadOptions(BOOL wait) {
+ /* default behavior */
+ NSMutableDictionary *options = [NSMutableDictionary dictionary];
+ options[ASDownloadOptionPriority] = ASDownloadPriorityNormal;
+
+ /* If an XPC interface is waiting on this, all expenses allowed */
+ if (wait) {
+ options[ASDownloadOptionPriority] = ASDownloadPriorityHigh;
+ options[ASDownloadOptionAllowBatteryPower] = @YES;
+ return options;
+ }
+
+ /* If last asset check-in was too long ago, use more expensive options */
+ SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
+ if (!SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessWarning)) {
+ secnotice("OTATrust", "Asset staleness state: warning");
+ options[ASDownloadOptionPriority] = ASDownloadPriorityHigh;
+ options[ASDownloadOptionAllowBatteryPower] = @YES;
+ } else if (!SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessAtRisk)) {
+ secnotice("OTATrust", "Asset staleness state: at risk");
+ options[ASDownloadOptionPriority] = ASDownloadPriorityHigh;
+ }
+ CFReleaseNull(otapkiref);
+ return options;
+}
+
static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) {
if (!CanCheckMobileAsset()) {
MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable,
continue;
}
- /* We got an Asset that this device could use; write the last check-in time as now. */
- (void)UpdateOTACheckInDate();
-
/* Check Content Version against the current content version */
NSNumber *contentVersion = [attributes objectForKey:ASAttributeContentVersion];
if (!ShouldUpdateWithAsset(contentVersion)) {
- MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem,
- @"skipping asset because we already have _ContentVersion %@ (or newer)", contentVersion);
+ /* write the version and last (successful) check-in time */
+ UpdateOTAContext(contentVersion, error);
+ NSDictionary *eventAttributes = @{
+ @"assetVersion" : contentVersion,
+ @"systemVersion" : @(GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey)),
+ @"installedVersion" : @(SecOTAPKIGetCurrentAssetVersion(nil)),
+ };
+ MakeOTATrustErrorWithAttributes(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, eventAttributes,
+ @"skipping asset because we already have _ContentVersion %@ (or newer)", contentVersion);
continue;
}
ASProgressHandler OTATrustHandler = ^(NSDictionary *state, NSError *progressError){
NSString *operationState = nil;
if (progressError) {
- secerror("progress handler failed: %@", progressError);
+ secerror("OTATrust: progress handler failed: %@", progressError);
LogRemotely(OTATrustLogLevelError, &progressError);
handler_error = [progressError copy];
if (wait) {
if (!state) {
MakeOTATrustError(&handler_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal,
- @"OTATrust: no asset state in progress handler");
+ @"no asset state in progress handler");
if (wait) {
dispatch_semaphore_signal(done);
}
dispatch_semaphore_signal(done);
}
}
- /* Other states keep calling our progress handler until so don't signal */
+ /* Other states keep calling our progress handler until completed so don't signal */
};
switch ([asset state]) {
secdebug("OTATrust", "OTATrust asset needs to be downloaded");
asset.progressHandler= OTATrustHandler;
asset.userInitiatedDownload = YES;
- [asset beginDownloadWithOptions:@{ASDownloadOptionPriority : ASDownloadPriorityNormal}];
+ [asset beginDownloadWithOptions:GetASDownloadOptions(wait)];
began_async_job = true;
break;
case ASAssetStateInstalled:
secdebug("OTATrust", "OTATrust asset download paused");
asset.progressHandler = OTATrustHandler;
asset.userInitiatedDownload = YES;
+ [asset adjustDownloadOptions:GetASDownloadOptions(wait) completion:nil];
if (![asset resumeDownloadAndReturnError:&localError]) {
if (localError) {
secerror("OTATrust: failed to resume download of asset: %@", localError);
secdebug("OTATrust", "OTATrust asset downloading");
asset.progressHandler = OTATrustHandler;
asset.userInitiatedDownload = YES;
+ [asset adjustDownloadOptions:GetASDownloadOptions(wait) completion:nil];
began_async_job = true;
break;
default:
int out_token = 0;
notify_register_dispatch(kOTATrustOnDiskAssetNotification, &out_token, queue, ^(int __unused token) {
secnotice("OTATrust", "Got notification about a new PKITrustSupplementals asset from system trustd.");
- UpdateFromAsset(GetAssetFileURL(nil), [NSNumber numberWithUnsignedLongLong:GetAssetVersion()]);
+ NSError *nserror = nil;
+ CFErrorRef error = nil;
+ NSNumber *asset_version = [NSNumber numberWithUnsignedLongLong:GetAssetVersion(&error)];
+ if (error) {
+ nserror = CFBridgingRelease(error);
+ }
+ if (!UpdateFromAsset(GetAssetFileURL(nil), asset_version, &nserror)) {
+ secerror("OTATrust: failed to update from asset after notification: %@", nserror);
+ /* Reset our last check-in time and reset the asset version to the system asset version -- even
+ * though we may be using something newer than that (but not as new as what's on disk). On re-launch
+ * (provided reading from disk still fails) we'd be using the system asset version anyway. */
+ SecOTAPKIResetCurrentAssetVersion(&error);
+ }
});
int out_token2 = 0;
notify_register_dispatch(kOTATrustCheckInNotification, &out_token2, queue, ^(int __unused token) {
static void TriggerPeriodicOTATrustAssetChecks(dispatch_queue_t queue) {
if (SecOTAPKIIsSystemTrustd()) {
static sec_action_t action;
+ static bool first_launch = true;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.security"];
secnotice("OTATrust", "Setting periodic update delta to %d seconds", delta);
action = sec_action_create_with_queue(queue,"OTATrust", delta);
sec_action_set_handler(action, ^{
- (void)DownloadOTATrustAsset(NO, NO, nil);
+ if (!first_launch) {
+ (void)DownloadOTATrustAsset(NO, NO, nil);
+ }
+ first_launch = false;
});
});
sec_action_perform(action);
return system_version;
}
+static bool initialization_error_from_asset_data = false;
+
static bool ShouldInitializeWithAsset(void) {
uint64_t system_version = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey);
- uint64_t asset_version = GetAssetVersion();
+ uint64_t asset_version = GetAssetVersion(nil);
if (asset_version > system_version) {
secnotice("OTATrust", "Using asset v%llu instead of system v%llu", asset_version, system_version);
- return true;
+ return !initialization_error_from_asset_data;
}
return false;
}
static CF_RETURNS_RETAINED CFArrayRef InitializeTrustedCTLogs() {
NSArray *trustedCTLogs = nil;
+ NSError *error = nil;
#if !TARGET_OS_BRIDGE
if (ShouldInitializeWithAsset()) {
- trustedCTLogs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustTrustedCTLogsFilename)];
+ trustedCTLogs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustTrustedCTLogsFilename) error:&error];
if (!isNSArray(trustedCTLogs)) {
- DeleteAssetFromDisk();
+ secerror("OTATrust: failed to read CT list from asset data: %@", error);
+ LogRemotely(OTATrustLogLevelError, &error);
+ if (!DeleteAssetFromDisk()) {
+ initialization_error_from_asset_data = true;
+ }
}
}
#endif
static CF_RETURNS_RETAINED CFDictionaryRef InitializeEventSamplingRates() {
NSDictionary *analyticsSamplingRates = nil;
NSDictionary *eventSamplingRates = nil;
+ NSError *error = nil;
#if !TARGET_OS_BRIDGE
if (ShouldInitializeWithAsset()) {
- analyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustAnalyticsSamplingRatesFilename)];
+ analyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustAnalyticsSamplingRatesFilename) error:&error];
if (!isNSDictionary(analyticsSamplingRates)) {
- DeleteAssetFromDisk();
+ secerror("OTATrust: failed to read sampling rates from asset data: %@", error);
+ LogRemotely(OTATrustLogLevelError, &error);
+ if (!DeleteAssetFromDisk()) {
+ initialization_error_from_asset_data = true;
+ }
}
eventSamplingRates = analyticsSamplingRates[@"Events"];
}
static CF_RETURNS_RETAINED CFArrayRef InitializeAppleCertificateAuthorities() {
NSArray *appleCAs = nil;
+ NSError *error = nil;
#if !TARGET_OS_BRIDGE
if (ShouldInitializeWithAsset()) {
- appleCAs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustAppleCertifcateAuthoritiesFilename)];
+ appleCAs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustAppleCertifcateAuthoritiesFilename) error:&error];
if (!isNSArray(appleCAs)) {
- DeleteAssetFromDisk();
+ secerror("OTATrust: failed to read Apple CAs list from asset data: %@", error);
+ LogRemotely(OTATrustLogLevelError, &error);
+ if (!DeleteAssetFromDisk()) {
+ initialization_error_from_asset_data = true;
+ }
}
}
#endif
static SecOTAPKIRef kCurrentOTAPKIRef = NULL;
/* This queue is for making changes to the OTAPKI reference */
static dispatch_queue_t kOTAQueue = NULL;
-/* This queue is for fetching changes to the OTAPKI reference or otherwise doing maintenance activities */
-static dispatch_queue_t kOTABackgroundQueue = NULL;
struct _OpaqueSecOTAPKI {
CFRuntimeBase _base;
return GetSystemVersion(CFSTR("VersionNumber"));
}
-static uint64_t GetAssetVersion(void) {
+static uint64_t GetAssetVersion(CFErrorRef *error) {
@autoreleasepool {
/* Get system asset version */
uint64_t version = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey);
#if !TARGET_OS_BRIDGE
uint64_t asset_version = 0;
- NSDictionary *OTAPKIContext = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustContextFilename)];
+ NSError *nserror = nil;
+ NSDictionary *OTAPKIContext = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustContextFilename) error:&nserror];
if (isNSDictionary(OTAPKIContext)) {
NSNumber *tmpNumber = OTAPKIContext[kOTATrustContentVersionKey];
if (isNSNumber(tmpNumber)) {
asset_version = [tmpNumber unsignedLongLongValue];
+ } else if (error) {
+ MakeOTATrustError(&nserror, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue,
+ @"OTAContext.plist missing version");
}
+ } else if (error) {
+ MakeOTATrustError(&nserror, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue,
+ @"OTAContext.plist missing dictionary");
}
if (asset_version > version) {
return asset_version;
} else {
- /* Delete old data */
- DeleteAssetFromDisk();
+ /* Don't delete the last check-in time so that we know we're up to date with the MobileAsset. */
+ if (error) {
+ /* only log this if we're tracking errors */
+ secnotice("OTATrust", "asset (%llu) is not newer than the system version (%llu); deleting stale data", asset_version, version);
+ *error = CFRetainSafe((__bridge CFErrorRef)nserror);
+ }
+ DeleteOldAssetData();
}
#endif
return version;
static CF_RETURNS_RETAINED CFDateRef InitializeLastAssetCheckIn(void) {
#if !TARGET_OS_BRIDGE
- NSDictionary *OTAPKIContext = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustContextFilename)];
+ NSError *error = nil;
+ NSDictionary *OTAPKIContext = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustContextFilename) error:&error];
if (isNSDictionary(OTAPKIContext)) {
NSDate *checkIn = OTAPKIContext[kOTATrustLastCheckInKey];
- return CFRetainSafe((__bridge CFDateRef)checkIn);
+ if (isNSDate(checkIn)) {
+ return CFRetainSafe((__bridge CFDateRef)checkIn);
+ } else {
+ MakeOTATrustError(&error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue,
+ @"OTAContext.plist missing check-in");
+ }
+ } else {
+ MakeOTATrustError(&error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue,
+ @"OTAContext.plist missing dictionary");
}
#endif
return NULL;
// Get the list of CAs used by Apple
otapkiref->_appleCAs = InitializeAppleCertificateAuthorities();
- // Get the asset version (after possible reset due to missing asset date)
- otapkiref->_assetVersion = GetAssetVersion();
- otapkiref->_lastAssetCheckIn = InitializeLastAssetCheckIn();
+ // Get the asset version (after possible reset due to missing asset data)
+ if (!initialization_error_from_asset_data) {
+ CFErrorRef error = nil;
+ otapkiref->_assetVersion = GetAssetVersion(&error);
+ otapkiref->_lastAssetCheckIn = InitializeLastAssetCheckIn();
+ CFReleaseNull(error);
+ } else {
+ otapkiref->_assetVersion = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey);
+ }
// Get the valid update snapshot version and format
CFIndex update_format = 0;
notify_post(kOTATrustCheckInNotification);
/* Update the on-disk check-in date, so when we re-launch we remember */
- return UpdateOTAContextOnDisk(kOTATrustLastCheckInKey, checkIn);
+ NSError *error = nil;
+ BOOL result = NO;
+ if (!(result = UpdateOTAContextOnDisk(kOTATrustLastCheckInKey, checkIn, &error))) {
+ secerror("OTATrust: failed to write last check-in time: %@", error);
+ }
+ return result;
} else {
return NO;
}
}
-static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version) {
+static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version, NSError **error) {
if (!localURL || !asset_version) {
- secerror("OTATrust: missing url and version for downloaded asset");
+ MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal,
+ @"missing url and version for downloaded asset");
return NO;
}
__block NSArray *newTrustedCTLogs = NULL;
NSURL *TrustedCTLogsFileLoc = [NSURL URLWithString:kOTATrustTrustedCTLogsFilename
relativeToURL:localURL];
- newTrustedCTLogs = [NSArray arrayWithContentsOfURL:TrustedCTLogsFileLoc];
+ newTrustedCTLogs = [NSArray arrayWithContentsOfURL:TrustedCTLogsFileLoc error:error];
if (!newTrustedCTLogs) {
- secerror("OTATrust: unable to create TrustedCTLogs from asset file: %@", TrustedCTLogsFileLoc);
+ secerror("OTATrust: unable to create TrustedCTLogs from asset file: %@", error ? *error: nil);
+ LogRemotely(OTATrustLogLevelError, error);
return NO;
}
NSURL *AnalyticsSamplingRatesFileLoc = [NSURL URLWithString:kOTATrustAnalyticsSamplingRatesFilename
relativeToURL:localURL];
- newAnalyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:AnalyticsSamplingRatesFileLoc];
+ newAnalyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:AnalyticsSamplingRatesFileLoc error:error];
if (!newAnalyticsSamplingRates) {
- secerror("OTATrust: unable to create AnalyticsSamplingRates from asset file: %@", AnalyticsSamplingRatesFileLoc);
+ secerror("OTATrust: unable to create AnalyticsSamplingRates from asset file: %@", error ? *error: nil);
+ LogRemotely(OTATrustLogLevelError, error);
return NO;
}
NSURL *AppleCAsFileLoc = [NSURL URLWithString:kOTATrustAppleCertifcateAuthoritiesFilename
relativeToURL:localURL];
- newAppleCAs = [NSArray arrayWithContentsOfURL:AppleCAsFileLoc];
+ newAppleCAs = [NSArray arrayWithContentsOfURL:AppleCAsFileLoc error:error];
if (!newAppleCAs) {
- secerror("OTATrust: unable to create AppleCAs from asset file: %@", AppleCAsFileLoc);
+ secerror("OTATrust: unable to create AppleCAs from asset file: %@", error ? *error: nil);
+ LogRemotely(OTATrustLogLevelError, error);
return NO;
}
/* Write the data to disk (so that we don't have to re-download the asset on re-launch) */
DeleteAssetFromDisk();
- if (CopyFileToDisk(kOTATrustTrustedCTLogsFilename, TrustedCTLogsFileLoc) &&
- CopyFileToDisk(kOTATrustAnalyticsSamplingRatesFilename, AnalyticsSamplingRatesFileLoc) &&
- CopyFileToDisk(kOTATrustAppleCertifcateAuthoritiesFilename, AppleCAsFileLoc) &&
- UpdateOTAContextOnDisk(kOTATrustContentVersionKey, asset_version)) {
+ if (CopyFileToDisk(kOTATrustTrustedCTLogsFilename, TrustedCTLogsFileLoc, error) &&
+ CopyFileToDisk(kOTATrustAnalyticsSamplingRatesFilename, AnalyticsSamplingRatesFileLoc, error) &&
+ CopyFileToDisk(kOTATrustAppleCertifcateAuthoritiesFilename, AppleCAsFileLoc, error) &&
+ UpdateOTAContext(asset_version, error)) { // Set version and check-in time last (after success)
/* If we successfully updated the "asset" on disk, signal the other trustds to pick up the changes */
notify_post(kOTATrustOnDiskAssetNotification);
+ } else {
+ return NO;
}
return YES;
CFArrayRef SecOTAPKICopyTrustedCTLogs(SecOTAPKIRef otapkiRef) {
CFArrayRef result = NULL;
- if (NULL == otapkiRef)
- {
+ if (NULL == otapkiRef) {
return result;
}
return CFRetainSafe(otapkiRef->_lastAssetCheckIn);
}
+bool SecOTAPKIAssetStalenessLessThanSeconds(SecOTAPKIRef otapkiRef, CFTimeInterval seconds) {
+ if (NULL == otapkiRef || !isDate(otapkiRef->_lastAssetCheckIn)) {
+ return false;
+ }
+ if(fabs([(__bridge NSDate *)otapkiRef->_lastAssetCheckIn timeIntervalSinceNow]) < seconds) {
+ return true;
+ }
+ return false;
+}
+
NSNumber *SecOTAPKIGetSamplingRateForEvent(SecOTAPKIRef otapkiRef, NSString *eventName) {
if (NULL == otapkiRef) {
return nil;
dispatch_sync(kOTAQueue, ^{
kCurrentOTAPKIRef->_assetVersion = system_version;
+ CFReleaseNull(kCurrentOTAPKIRef->_lastAssetCheckIn);
+ kCurrentOTAPKIRef->_lastAssetCheckIn = NULL;
});
#if !TARGET_OS_BRIDGE
}
uint64_t SecOTAPKISignalNewAsset(CFErrorRef* error) {
+ NSError *nserror = nil;
+ uint64_t version = 0;
#if !TARGET_OS_BRIDGE
if (SecOTAPKIIsSystemTrustd()) {
- NSError *nserror = nil;
if (!DownloadOTATrustAsset(NO, YES, &nserror) && error) {
*error = CFRetainSafe((__bridge CFErrorRef)nserror);
}
} else {
SecError(errSecServiceNotAvailable, error, CFSTR("This function may ony be performed by the system trustd."));
}
- return GetAssetVersion();
+ version = GetAssetVersion(nil);
#else
SecError(errSecUnsupportedService, error, CFSTR("This function is not available on this platform"));
- return GetAssetVersion();
+ version = GetAssetVersion(error);
#endif
+ return version;
}