Язык требования подписывания кода
Когда Вы используете codesign
команда для подписания блока кода можно указать внутренние требования; т.е. критерии, которые Вы рекомендуете, должны использоваться для оценки подписи кода. Это до верификатора, чтобы решить, применить ли внутренние требования или некоторый другой набор требований при решении, как обработать код со знаком. Вы используете язык требования кода, описанный в этой главе при указании требований к codesign
или csreq
команда (см. страницы руководства для codesign(1)
и csreq(1)
).
В этой главе описываются исходный код языка требования. Можно скомпилировать ряд требований и сохранить их в двоичной форме с помощью csreq
команда. Можно обеспечить требования для codesign
команда или как исходный код или как двоичный файл. Оба codesign
и csreq
команды могут преобразовать двоичный набор требования в текст. Несмотря на то, что существует некоторая гибкость в синтаксисе исходного кода (например, кавычки могут всегда использоваться вокруг строковых констант, но не всегда требуются), преобразование от двоичного файла до текста всегда использует ту же форму:
Круглые скобки помещаются (обычно только) при необходимости для разъяснения приоритета оператора.
Строковые константы заключаются в кавычки (обычно только) при необходимости.
Возвращаются ли первоначально указанный как константы или через пути к файлам, хеши сертификата всегда как константы хеша.
Комментарии в первоисточнике не сохраняются в восстановленном тексте.
Синтаксис языка
Некоторые основные характеристики синтаксиса языка:
Выражения используют стандартную инфиксную нотацию (т.е. оператор размещается между этими двумя объектами, действующего на; например, количество
<
постоянный).Ключевые слова резервируются, но могут быть заключены в кавычки, чтобы быть включенными как часть обычных строк.
Комментарии позволяются в C, Objective C и C++.
Неупомянутый пробел позволяется между маркерами, но строки, содержащие пробел, должны быть заключены в кавычки.
Окончания строки не имеют никакого особого значения и обрабатываются как пробел.
Оценка требований
Требование составляет выражение без побочных эффектов. Каждое требование может иметь любое число подвыражений, каждое из которых оценено с булевской переменной (следовать-сбой) результат. Нет никакого определенного порядка оценки. Подвыражения объединены с помощью логических операторов в выражении для получения полного булева результата для выражения. Даже если некоторые подвыражения перестали работать, В зависимости от используемых операторов может успешно выполниться выражение. Например, выражение
anchor apple or anchor = "/var/db/yourcorporateanchor.cert" |
успешно выполняется, если любое подвыражение успешно выполняется — т.е. если код был подписан или Apple или Вашей компанией — даже при том, что одно из подвыражений, несомненно, перестанет работать.
Если ошибка происходит во время оценки, с другой стороны, оценка сразу останавливается и codesign
или csreq
команда возвращается с кодом результата, указывающим причину отказа.
Константы
В этом разделе описываются использование строки, целого числа, значения хэш-функции и двоичных констант на языке требования подписывания кода.
Строковые константы
Строковые константы должны быть включены двойными кавычками (" "
) если строка не содержит только буквы, цифры, и периоды (.), когда кавычки являются дополнительными. Абсолютные пути к файлам, запускающиеся с наклонной черты, не требуют кавычек, если они не содержат пробелы. Например:
com.apple.mail //no quotes are required |
"com.apple.mail" //quotes are optional |
"My Company's signing identity" //requires quotes for spaces and apostrophe |
/Volumes/myCA/root.crt //no quotes are required |
"/Volumes/my CA/root.crt" //space requires quotes |
"/Volumes/my_CA/root.crt" //underscore requires quotes |
Никогда не неправильно включить строку в кавычки — если в сомнении, используйте кавычки.
Используйте наклонную черту влево, чтобы «выйти» из любого символа. Например:
"one \" embedded quote" //one " embedded quote |
"one \\ embedded backslash" //one \ embedded backslash |
Нет ничего специального о символе одинарной кавычки (').
Целочисленные константы
Целочисленные константы записаны, как десятичные константы находятся в C. Язык не позволяет префиксы основания (такой как 0x
) или продвижение плюс или минус (+
или -
) знаки.
Константы хеша
Значения хэш-функции записаны любой как шестнадцатеричное число в кавычках, которым предшествуют H
, или как путь к файлу, содержащему двоичный сертификат. При использовании первой формы число должно включать точное число цифр в значении хэш-функции. Хеш SHA 1 (единственный вид, в настоящее время поддерживаемый), требует точно 40 цифр; например:
H"0123456789ABCDEFFEDCBA98765432100A2BC5DA" |
Можно использовать или прописные или строчные буквы (A..F
или a..f
) в шестнадцатеричных числах.
При указании пути к файлу компилятор читает двоичный сертификат и вычисляет хеш для Вас. Скомпилированная версия кода требования включает только хеш; файл сертификата и путь не сохраняются. При преобразовании требования назад в текст Вы получаете шестнадцатеричный постоянный хеш. Путь к файлу должен указать на файл, содержащий закодированный сертификат DER X.509. Никакие контейнерные формы (PKCS7, PKCS12) не позволяются, и при этом форма OpenSSL «PEM» не поддерживается.
Переменные
На языке требования в настоящее время нет никаких переменных.
Логические операторы
Язык требования включает следующие логические операторы, в порядке уменьшающегося приоритета:
!
(отрицание)and
(логический AND)or
(логический OR)
Эти операторы могут использоваться для объединения подвыражений в более сложные выражения. Оператор отрицания (!
) унарный префиксный оператор. Другие - инфиксные операторы. Круглые скобки могут использоваться для переопределения приоритета операторов.
Поскольку язык свободен от побочных эффектов, порядок оценки подвыражений является неуказанным.
Операции сравнения
Язык требования включает следующие операторы сравнения:
=
(равняется)<
(меньше, чем)>
(больше, чем)<=
(меньше чем или равный)>=
(больше, чем или равный)exists
(значение присутствует),
Настоящее значения (exists
) оператор является унарным суффиксным оператором. Другие - инфиксные операторы.
Нет никаких операторов для несоответствий (не равны, не больше, чем, и т.д.). Используйте оператора отрицания (!
) вместе с операторами сравнения, чтобы сделать сравнения несоответствия.
Равенство
Все операции равенства сравнивают некоторое значение с константой. Значение и постоянный должно иметь тот же тип: строка соответствует строковую константу, значение данных соответствует шестнадцатеричную константу. Работа равенства оценивает к true
если значение существует и равно константе. Сопоставление строк использует те же правила соответствия как CFString
(см. ссылку CFString).
В выражениях соответствия (см. Информацию, Часть Сертификата и Право), подстроки строковых констант могут быть соответствующими при помощи *
подстановочный символ:
value = *constant*
true
если значение существует, и любая подстрока значения соответствует константу; например:thunderbolt = *under*
thunderbolt = *thunder*
thunderbolt = *bolt*
value = constant*
true
если значение существует и начинается с константы; например:thunderbolt = thunder*
thunderbolt = thun*
value = *constant
true
если значение существует и заканчивается константой; например:thunderbolt = *bolt
thunderbolt = *underbolt
Если константа записана с кавычками, звездочки должны быть вне кавычек. Звездочка в кавычках взята буквально. Например:
"ten thunderbolts" = "ten thunder"*
true
"ten thunder*bolts" = "ten thunder*"*
true
"ten thunderbolts" = "ten thunder*"
false
Неравенство
Операции неравенства сравнивают некоторое значение с константой. Значение и постоянный должно иметь тот же тип: строка соответствует строковую константу, значение данных соответствует шестнадцатеричную константу. Сравнения строк используют те же правила соответствия как CFString
с kCFCompareNumerically
флаг опции; например, "17.4"
больше, чем "7.4"
.
Существование
Оператор существования тестирует, существует ли значение. Это оценивает к false
только если значение не существует вообще или является точно булевым значением false
. Пустая строка и число 0
как полагают, существуют.
Ограничения
Несколько ключевых слов на языке требования используются, чтобы потребовать что определенные сертификаты присутствовать или другие условия быть встреченными.
Идентификатор
Выражение
identifier =
постоянный
если строка уникального идентификатора, встроенная в подпись кода, точно равна константе, успешно выполняется. Знак «равно» является дополнительным в выражениях идентификатора. Подписание идентификаторов может быть протестировано только на точное равенство; подстановочный символ (*
) не может использоваться с ограничением идентификатора, и при этом идентификаторы не могут быть протестированы на неравенство.
Информация
Выражение
info [
ключ]
выражение соответствия
если значение, связанное с верхним уровнем, вводит код, успешно выполняется info.plist
файл соответствует выражение соответствия, где выражение соответствия может включать любого из операторов, перечисленных в Операциях Сравнения и Логических операторах. Например:
info [CFBundleShortVersionString] < "17.4" |
или
info [MySpecialMarker] exists |
Необходимо указать ключ как строковую константу.
Если значение указанного ключа является строкой, соответствие применяется к нему непосредственно. Если значение является массивом, это должен быть массив строк, и соответствие сделано каждому, в свою очередь, следованием, если соответствует какой-либо из них. Подстроки строковых констант могут быть соответствующими при помощи любого выражения соответствия (см. Операции Сравнения).
Если код имеет нет info.plist
файл, или info.plist
не содержит указанный ключ, это выражение оценивает к false
не возвращая ошибку.
Сертификат
Ограничения сертификата обращаются к сертификатам в цепочке сертификата, используемой для проверки подписи. Большая часть использования certificate
ключевое слово принимает целое число, указывающее позицию сертификата в цепочке: положительные целые числа рассчитывают от листа (0) к привязке. Отрицательные целые числа рассчитывают назад от привязки (-1). Например, certificate 1
промежуточный сертификат, использовавшийся для подписания листа (т.е. сертификат подписания), и certificate -2
указывает сертификат, непосредственно подписанный привязкой. Обратите внимание на то, что это соглашение совпадает с, который использовал для индексации массива в языках программирования Ruby и Perl:
Привязка | Первое промежуточное звено | Второе промежуточное звено | Лист |
---|---|---|---|
|
|
|
|
|
|
|
|
Другие ключевые слова включают:
certificate root
— сертификат привязки; то же как сертификат 0anchor
— то же какcertificate root
certificate leaf
— сертификат подписания; то же какcertificate -1
Если нет никакого сертификата в указанной позиции, ограничение оценивает к false
не возвращая ошибку.
Если код был подписан с помощью оперативной подписи, нет никаких сертификатов вообще, и все ограничения сертификата оценивают к false
. (Оперативная подпись создается путем подписания с псевдоидентификационными данными -
(тире). Оперативная подпись не использует или записывает криптографические идентификационные данные, и таким образом идентифицирует точно и только одна подписываемая программа.)
Если код был подписан самоподписанным сертификатом, то лист и корень обращаются к тому же единственному сертификату.
Целый сертификат
Чтобы потребовать, чтобы определенный сертификат присутствовал в цепочке сертификата, используйте форму
certificate
позиция =
хеш
или одна из эквивалентных форм, обсужденных выше, такой как anchor =
хеш. Константы хеша описаны в Константах Хеша.
Для собственного кода Apple, подписанного Apple, можно использовать краткую форму
anchor apple
Для кода, подписанного Apple, включая код использование со знаком сертификата подписания, выпущенного Apple другим разработчикам, используют форму
anchor apple generic
Часть сертификата
Для соответствия четко определенного элемента сертификата используйте форму
certificate
позиция[
элемент]
выражение соответствия
где выражение соответствия может включать *
подстановочный символ и любой из операторов, перечисленных в Логических операторах и Операциях Сравнения. В настоящее время поддерживаемые элементы следующие:
Имя элемента | Значение | Комментарии |
---|---|---|
| Подчиненное общее название | Показанный в утилите Keychain Access |
| Подчиненное название страны | |
| Подчиненное описание | |
| Подчиненная местность | |
| Подчиненная организация | Обычно компания или организация |
| Подчиненная организационная единица | |
| Подчиненный адрес расположения |
Поле Certificate OID
Для проверки на существование любого поля сертификата, идентифицированного его идентификатором объекта X.509 (OID), используйте форму
certificate
позиция [field.
OID] exists
Идентификатор объекта должен быть записан в числовой форме (x.
y.
z...), и может быть OID расширения сертификата или стандартного элемента сертификата, как определено стандартом CSSM (см. Главу 31 в Коллективной безопасности: CDSA и CSSM, версия 2 (с исправлениями) Open Group (http://www .opengroup.org/security/cdsa.htm)).
Доверяемый
Выражение
certificate
позиция trusted
если сертификат, указанный позицией, отмечен доверяемый для политики сертификата для подписывания кода в базе данных Trust Settings системы, успешно выполняется. Параметром позиции является целое число или ключевое слово, указывающее позицию сертификата в цепочке; посмотрите обсуждение в соответствии с Сертификатом.
Выражение
anchor trusted
успешно выполняется, если какой-либо сертификат в цепочке сертификата подписи отмечен доверяемый для политики сертификата для подписывания кода в базе данных Trust Settings системы, при условии, что никакой сертификат ближе листовому сертификату не явно недоверяем.
Таким образом, использование trusted
ключевое слово с позицией сертификата проверяет только указанный сертификат при использовании его с anchor
ключевое слово проверяет все сертификаты, давая приоритет установке доверия, найденной самой близкой к листу.
Сертификаты могут иметь доверительные настройки в расчете на пользователя и в масштабе всей системы доверять настройкам и положить, что настройки применяются к определенным политикам. trusted
ключевое слово на языке требования подписывания кода заставляет доверие быть проверенным на указанный сертификат или сертификаты для пользователя, выполняющего проверку. Если нет никаких настроек для того пользователя, то параметры настройки системы используются. Во всех случаях только проверяются доверительные настройки для политики подписывания кода. Политики и доверие обсуждены в Сертификате, Ключе и Руководстве по программированию Trust Services.
Право
Выражение
entitlement [
ключ]
выражение соответствия
успешно выполняется, если значение связалось с указанным ключом во встроенном дающем право выражении соответствия соответствий словаря подписи, где выражение соответствия может включать *
подстановочный символ и любой из операторов, перечисленных в Логических операторах и Операциях Сравнения. Необходимо указать ключ как строковую константу. Дающий право словарь включен в подписи для определенных платформ.
Хеш каталога кода
Выражение
cdhash
постоянный хешем
если значение этого хеша точно равняется указанному постоянному хешу, вычисляет хеш SHA 1 ресурса CodeDirectory программы и успешно выполняется.
Ресурс CodeDirectory является основным каталогом содержания программы. Это состоит из имеющего версию заголовка, сопровождаемого массивом хешей. Этот массив состоит из ряда дополнительных специальных хешей для других ресурсов плюс вектор хешей для страниц основной исполнимой программы. Ресурсы CodeSignature и CodeDirectory вместе составляют подпись кода.
Можно использовать утилиту элемента кода с (по крайней мере) тремя уровнями многословия для получения хеша, постоянного из ресурса CodeDirectory программы:
$ codesign -dvvv /bin/ls |
... |
CodeDirectory v=20001 size=257 flags=0x0(none) hashes=8+2 location=embedded |
CDHash=4bccbc576205de37914a3023cae7e737a0b6a802 |
... |
Поскольку каталог кода изменяется каждый раз, когда изменения программы нетривиальным способом, этот тест может использоваться для однозначной идентификации одной определенной версии программы. Когда операционная система подписывает иначе программу без знака (так, чтобы цепочка для ключей или Родительский контроль могли распознать программу, например), это использует это требование.
Наборы требования
Набор требования является набором отличных требований, каждый индексированный (теговый) с кодом типа. Выражение
тег =>
требование
применяет требование к типу кода, обозначенного тегом, где возможные теги
host
— это требование применяется к прямому узлу этого модуля кода; каждый модуль кода по пути хостинга может иметь свое собственное требование узла, где путь хостинга является цепочкой узлов подписывания кода начиная с самого определенного кода, который, как известно, работал и заканчиваться корнем доверия (ядро)guest
— это требование применяется к каждому модулю кода, размещающемуся этим модулем кодаlibrary
— это требование применяется ко всем библиотекам, смонтированным кодом со знакомdesignated
— это - явно указанное определяемое требование для кода со знаком; если нет никакого явно указанного определяемого требования для кода, то существует нетdesignated
внутреннее требование
Основное использование наборов требования должно представлять внутренние требования кода со знаком. Например:
codesign -r='host => anchor apple and identifier com.apple.perl designated => anchor /my/root and identifier com.bar.foo' |
устанавливает внутренние требования некоторого кода, имея требование узла anchor apple and identifier com.apple.perl
(“Я - сценарий Perl, и я хочу быть выполненным интерпретатором Perl Apple”), и явное определяемое требование anchor /my/root and identifier com.bar.foo
. Обратите внимание на то, что это наборы команд никакой гость или требования библиотеки.
Можно также поместить набор требования в файл и указать на файл:
codesign -r myrequirements.rqset |
где файл myrequirements.rqset
мог бы содержать:
//internal requirements |
host => anchor apple and identifier com.apple.perl //require Apple's Perl interpreter |
designated => anchor /my/root and identifier com.bar.foo |