/** @file * IPRT - Apple Code Signing Structures and APIs. */ /* * Copyright (C) 2018-2019 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the * VirtualBox OSE distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. */ #ifndef IPRT_INCLUDED_crypto_applecodesign_h #define IPRT_INCLUDED_crypto_applecodesign_h #ifndef RT_WITHOUT_PRAGMA_ONCE # pragma once #endif #include #include #include /** @defgroup grp_rt_craplcs RTCrAppleCs - Apple Code Signing * @ingroup grp_rt_crypto * @{ */ /** Apple developer ID for application signing. */ #define RTCR_APPLE_CS_DEVID_APPLICATION_OID "1.2.840.113635.100.6.1.13" /** Apple developer ID for installer signing. */ #define RTCR_APPLE_CS_DEVID_INSTALLER_OID "1.2.840.113635.100.6.1.14" /** Apple developer ID for kernel extension signing. */ #define RTCR_APPLE_CS_DEVID_KEXT_OID "1.2.840.113635.100.6.1.18" /** Apple certificate policy OID. */ #define RTCR_APPLE_CS_CERTIFICATE_POLICY_OID "1.2.840.113635.100.5.1" /** @name RTCRAPLCS_MAGIC_XXX - Apple code signing magic values for identifying blobs * @note No byte order conversion required. * @{ */ #define RTCRAPLCS_MAGIC_BLOBWRAPPER RT_N2H_U32_C(UINT32_C(0xfade0b01)) #define RTCRAPLCS_MAGIC_EMBEDDED_SIGNATURE_OLD RT_N2H_U32_C(UINT32_C(0xfade0b02)) #define RTCRAPLCS_MAGIC_REQUIREMENT RT_N2H_U32_C(UINT32_C(0xfade0c00)) #define RTCRAPLCS_MAGIC_REQUIREMENTS RT_N2H_U32_C(UINT32_C(0xfade0c01)) #define RTCRAPLCS_MAGIC_CODEDIRECTORY RT_N2H_U32_C(UINT32_C(0xfade0c02)) #define RTCRAPLCS_MAGIC_EMBEDDED_SIGNATURE RT_N2H_U32_C(UINT32_C(0xfade0cc0)) #define RTCRAPLCS_MAGIC_DETACHED_SIGNATURE RT_N2H_U32_C(UINT32_C(0xfade0cc1)) /** @} */ /** @name Apple code signing versions. * @note Requires byte order conversion of the field value. That way * greater-than and less-than comparisons works correctly. * @{ */ #define RTCRAPLCS_VER_2_0 UINT32_C(0x00020000) #define RTCRAPLCS_VER_SUPPORTS_SCATTER UINT32_C(0x00020100) #define RTCRAPLCS_VER_SUPPORTS_TEAMID UINT32_C(0x00020200) #define RTCRAPLCS_VER_SUPPORTS_CODE_LIMIT_64 UINT32_C(0x00020300) #define RTCRAPLCS_VER_SUPPORTS_EXEC_SEG UINT32_C(0x00020400) /** @} */ /** @name RTCRAPLCS_SLOT_XXX - Apple code signing slots. * @note No byte order conversion required. * @{ */ #define RTCRAPLCS_SLOT_CODEDIRECTORY RT_N2H_U32_C(UINT32_C(0x00000000)) #define RTCRAPLCS_SLOT_INFO RT_N2H_U32_C(UINT32_C(0x00000001)) #define RTCRAPLCS_SLOT_REQUIREMENTS RT_N2H_U32_C(UINT32_C(0x00000002)) #define RTCRAPLCS_SLOT_RESOURCEDIR RT_N2H_U32_C(UINT32_C(0x00000003)) #define RTCRAPLCS_SLOT_APPLICATION RT_N2H_U32_C(UINT32_C(0x00000004)) #define RTCRAPLCS_SLOT_ENTITLEMENTS RT_N2H_U32_C(UINT32_C(0x00000005)) #define RTCRAPLCS_SLOT_ALTERNATE_CODEDIRECTORIES RT_N2H_U32_C(UINT32_C(0x00001000)) #define RTCRAPLCS_SLOT_ALTERNATE_CODEDIRECTORIES_END RT_N2H_U32_C(UINT32_C(0x00001005)) #define RTCRAPLCS_SLOT_ALTERNATE_CODEDIRECTORIES_COUNT UINT32_C(0x00000005) #define RTCRAPLCS_SLOT_ALTERNATE_CODEDIRECTORY_INC RT_N2H_U32_C(UINT32_C(0x00000001)) /** The signature. * This is simply a RTCRAPLCSHDR/RTCRAPLCS_MAGIC_BLOBWRAPPER followed by a DER * encoded \#PKCS7 ContentInfo structure containing signedData. The inner * signedData structure signs external data, so its ContentInfo member is set * to 1.2.840.113549.1.7.1 and has no data. */ #define RTCRAPLCS_SLOT_SIGNATURE RT_N2H_U32_C(UINT32_C(0x00010000)) /** @} */ /** @name RTCRAPLCS_HASHTYPE_XXX - Apple code signing hash types * @note Byte sized field, so no byte order concerns. * @{ */ #define RTCRAPLCS_HASHTYPE_SHA1 UINT8_C(1) #define RTCRAPLCS_HASHTYPE_SHA256 UINT8_C(2) #define RTCRAPLCS_HASHTYPE_SHA256_TRUNCATED UINT8_C(3) /**< Truncated to 20 bytes (SHA1 size). */ #define RTCRAPLCS_HASHTYPE_SHA384 UINT8_C(4) /** @} */ /** * Apple code signing blob header. */ typedef struct RTCRAPLCSHDR { /** The magic value (RTCRAPLCS_MAGIC_XXX). * (Big endian, but constant are big endian already.) */ uint32_t uMagic; /** The total length of the blob. Big endian. */ uint32_t cb; } RTCRAPLCSHDR; AssertCompileSize(RTCRAPLCSHDR, 8); /** Pointer to a CS blob header. */ typedef RTCRAPLCSHDR *PRTCRAPLCSHDR; /** Pointer to a const CS blob header. */ typedef RTCRAPLCSHDR const *PCRTCRAPLCSHDR; /** * Apple code signing super blob slot. */ typedef struct RTCRAPLCSBLOBSLOT { /** Slot type, RTCRAPLCS_SLOT_XXX. * (Big endian, but so are the constants too). */ uint32_t uType; /** Data offset. Big endian. */ uint32_t offData; } RTCRAPLCSBLOBSLOT; AssertCompileSize(RTCRAPLCSBLOBSLOT, 8); /** Pointer to a super blob slot. */ typedef RTCRAPLCSBLOBSLOT *PRTCRAPLCSBLOBSLOT; /** Pointer to a const super blob slot. */ typedef RTCRAPLCSBLOBSLOT const *PCRTCRAPLCSBLOBSLOT; /** * Apple code signing super blob. */ typedef struct RTCRAPLCSSUPERBLOB { /** Header (uMagic = RTCRAPLCS_MAGIC_EMBEDDED_SIGNATURE? * or RTCRAPLCS_MAGIC_EMBEDDED_SIGNATURE_OLD? ). */ RTCRAPLCSHDR Hdr; /** Number of slots. Big endian. */ uint32_t cSlots; /** Slots. */ RTCRAPLCSBLOBSLOT aSlots[RT_FLEXIBLE_ARRAY]; } RTCRAPLCSSUPERBLOB; AssertCompileMemberOffset(RTCRAPLCSSUPERBLOB, aSlots, 12); /** Pointer to a CS super blob. */ typedef RTCRAPLCSSUPERBLOB *PRTCRAPLCSSUPERBLOB; /** Pointer to a const CS super blob. */ typedef RTCRAPLCSSUPERBLOB const *PCRTCRAPLCSSUPERBLOB; /** * Code directory (RTCRAPLCS_MAGIC_CODEDIRECTORY). */ typedef struct RTCRAPLCSCODEDIRECTORY { /** 0x00: Header (uMagic = RTCRAPLCS_MAGIC_CODEDIRECTORY). */ RTCRAPLCSHDR Hdr; /** 0x08: The version number (RTCRAPLCS_VER_XXX). * @note Big endian, host order constants. */ uint32_t uVersion; /** 0x0c: Flags & mode, RTCRAPLCS_???. (Big endian. ) */ uint32_t fFlags; /** 0x10: Offset of the hash slots. Big endian. * Special slots found below this offset, code slots at and after. */ uint32_t offHashSlots; /** 0x14: Offset of the identifier string. Big endian. */ uint32_t offIdentifier; /** 0x18: Number of special hash slots. Hubertus Bigend style. */ uint32_t cSpecialSlots; /** 0x1c: Number of code hash slots. Big endian. */ uint32_t cCodeSlots; /** 0x20: Number of bytes of code that's covered, 32-bit wide. Big endian. */ uint32_t cbCodeLimit32; /** 0x24: The hash size. */ uint8_t cbHash; /** 0x25: The hash type (RTCRAPLCS_HASHTYPE_XXX). */ uint8_t bHashType; /** 0x26: Platform identifier or zero. */ uint8_t idPlatform; /** 0x27: The page shift value. zero if infinite page size. */ uint8_t cPageShift; /** 0x28: Spare field, MBZ. */ uint32_t uUnused1; /** 0x2c: Offset of scatter vector (optional). Big endian. * @since RTCRAPLCS_VER_SUPPORTS_SCATTER */ uint32_t offScatter; /** 0x30: Offset of team identifier (optional). Big endian. * @since RTCRAPLCS_VER_SUPPORTS_TEAMID */ uint32_t offTeamId; /** 0x34: Unused field, MBZ. * @since RTCRAPLCS_VER_SUPPORTS_CODE_LIMIT_64 */ uint32_t uUnused2; /** 0x38: Number of bytes of code that's covered, 64-bit wide. Big endian. * @since RTCRAPLCS_VER_SUPPORTS_CODE_LIMIT_64 */ uint64_t cbCodeLimit64; /** 0x40: File offset of the first segment. Big endian. * @since RTCRAPLCS_VER_SUPPORTS_EXEC_SEG */ uint64_t offExecSeg; /** 0x48: The size of the first segment. Big endian. * @since RTCRAPLCS_VER_SUPPORTS_EXEC_SEG */ uint64_t cbExecSeg; /** 0x50: Flags for the first segment. Big endian. * @since RTCRAPLCS_VER_SUPPORTS_EXEC_SEG */ uint64_t fExecSeg; } RTCRAPLCSCODEDIRECTORY; AssertCompileSize(RTCRAPLCSCODEDIRECTORY, 0x58); /** Pointer to a CS code directory. */ typedef RTCRAPLCSCODEDIRECTORY *PRTCRAPLCSCODEDIRECTORY; /** Pointer to a const CS code directory. */ typedef RTCRAPLCSCODEDIRECTORY const *PCRTCRAPLCSCODEDIRECTORY; /** * IPRT structure for working with an Apple code signing blob. */ typedef struct RTCRAPLCS { uint8_t const *pbBlob; size_t cbBlob; size_t auReserved[4]; } RTCRAPLCS; /** Pointer to an IPRT CS blob descriptor. */ typedef RTCRAPLCS *PRTCRAPLCS; /** * Initialize a RTCRAPLCS descriptor and validate the blob data. * * @returns IPRT status code. * @param pDesc The descirptor to initialize. * @param pvBlob The blob bytes. * @param cbBlob The number of bytes in the blob. * @param fFlags Future validation flags, MBZ. * @param pErrInfo Where to return additional error details. Optional. */ RTDECL(int) RTCrAppleCsInit(PRTCRAPLCS pDesc, void const *pvBlob, size_t cbBlob, uint32_t fFlags, PRTERRINFO pErrInfo); /** * Callback used by RTCrAppleCsVerifyImage to digest a section of the image. * * @return IPRT status code. * @param hDigest The digest to feed the bytes to. * @param off The RVA of the bytes to digest. * @param cb Number of bytes to digest. * @param pvUser User argument. */ typedef DECLCALLBACK(int) FNRTCRAPPLECSDIGESTAREA(RTCRDIGEST hDigest, size_t off, size_t cb, void *pvUser); /** Pointer to a image digest callback. */ typedef FNRTCRAPPLECSDIGESTAREA *PFNRTCRAPPLECSDIGESTAREA; /** * Verifies an image against the given signature blob. * * @return IPRT status code. * @param pDesc The apple code signing blob to verify against. * @param fFlags Future verification flags, MBZ. * @param pfnCallback Image digest callback. * @param pvUser User argument for the callback. * @param pErrInfo Where to return additional error details. Optional. */ RTDECL(int) RTCrAppleCsVerifyImage(PRTCRAPLCS pDesc, uint32_t fFlags, PFNRTCRAPPLECSDIGESTAREA pfnCallback, void *pvUser, PRTERRINFO pErrInfo); RTDECL(int) RTCrAppleCsQuerySigneddData(PRTCRAPLCS pDesc, PRTCRPKCS7SIGNEDDATA pSignedData, PRTERRINFO pErrInfo); /** @} */ #endif /* !IPRT_INCLUDED_crypto_applecodesign_h */