Создание сервера профиля для сверхвоздушной регистрации и конфигурации

При создании сервера профиля необходимо выполнить несколько шагов:

  1. Сконфигурируйте свою инфраструктуру. Это описано в Конфигурировании Инфраструктуры.

  2. Получите сертификат SSL для своего сервера. Это описано в Получении сертификата SSL.

  3. Создайте шаблонный профиль конфигурации. Это описано в Создании Шаблонного Профиля Конфигурации.

  4. Создайте серверный код. Части сервера описаны в Запуске Обработчиков Службы Сервера и Профиля.

  5. Добавьте надлежащую аутентификацию, определенную для Вашей среды.

  6. Протестируйте службу.

Следующие разделы берут Вас через различные части исходного кода услуги по доставке профиля.

Конфигурирование инфраструктуры

Сверхвоздушная регистрация реализации и конфигурация требуют, чтобы Вы интегрировали аутентификацию, каталог и службы сертификата. Процесс может быть развернут с помощью стандартных веб-сервисов, но необходимо установить несколько ключевых систем заранее.

Службы каталогов

Для аутентификации пользователя можно использовать основную Аутентификацию HTTP или интегрировать аутентификацию с существующими службами каталогов. Независимо от используемых служб необходимо будет предоставить веб-метод аутентификации пользователям запросить регистрацию.

Certificate Services

Процесс регистрации требует развертывания стандарта x.509 удостоверения личности пользователям iOS. Чтобы сделать это, Вам будет нужен CA (центр сертификации) для выпуска учетных данных устройства с помощью Simple Certificate Enrollment Protocol (SCEP).

Cisco IOS и Microsoft Server 2003 (с дополнением для служб сертификата) обе поддержки SCEP. Существует также много размещенных служб PKI, поддерживающих SCEP, такой как Verisign, Поручающих, и RSA. Для ссылок к PKI SCEP и связанные разделы читают раздел See Also во Введении.

Profile Services

Для реализации этого процесса, необходимо будет разработать службу профиля, которая является основанным на HTTP демоном, управляющим основанными на iOS подключениями устройства в течение процесса, генерирующим профили конфигурации для пользователя и проверяющим удостоверения пользователя по пути.

Существует несколько ключевых функций, которые должна обеспечить служба профиля:

  • Разместите доступный для пользователя веб-сайт для поддержки сеанса HTTPS

  • Аутентифицируйте входящие пользовательские запросы с помощью веб-метода аутентификации (основной, или интегрированный со службами каталогов)

  • Генерируйте необходимые профили конфигурации (формат XML) в зависимости от фазы процесса

  • Подпишите и зашифруйте профили конфигурации с помощью шифрования с открытым ключом

  • Отследите пользователя через шаги в процессе (через метку времени и методы журналирования)

  • Управляйте соединениями с центром сертификации или службами каталогов

Получение сертификата SSL

Первый шаг в установке службы профиля должен получить или генерировать сертификат SSL для веб-сервера. При хостинге сервера профиля каждое основанное на iOS устройство должно быть в состоянии сделать безопасное соединение с сервером. Самый простой способ сделать это должно получить сертификат SSL от общедоступного CA, которому уже доверяет iOS. Для полного списка посмотрите iOS 3.0: Список Доступных Доверяемых Корневых Сертификатов.

Также можно генерировать собственный корневой сертификат и самоподписать его, хотя, если Вы делаете, пользователя спросят, доверяют ли они сертификату.

Создание шаблонного профиля конфигурации

Служба профиля использует шаблонный профиль конфигурации в качестве начальной точки, затем изменяет профиль для определенного устройства. Необходимо создать этот шаблон заранее и сохранить его к файлу на диске. Утилита Конфигурации iPhone обеспечивает простые средние значения создания такого основного профиля.

В дополнение к общим настройкам этот профиль конфигурации должен также определить политики предприятия, что Вы хотите осуществить. Для оборудования находившегося в собственности компании это должен быть закрывший профиль, чтобы препятствовать тому, чтобы пользователь удалил его из устройства.

Для получения дополнительной информации об этих профилях, считайте “Формат Профиля Конфигурации” в Руководстве по развертыванию Предприятия.

Запуск сервера

После того, как у Вас будет сертификат SSL, необходимо сконфигурировать веб-сервер для хостинга службы профиля и осведомленного о SCEP центра сертификации к свидетельствам о выпуске.

Функция инициализации, init, загружает сертификат сервера HTTP и частный ключ SSL. Эти ключи и сертификаты сохранены на диске для повторного использования вместе с порядковым номером последнего выпущенного сертификата. Эта функция показана в Перечислении 2-1.

Перечисление 2-1  , Начинающее веб-сервер

world = WEBrick::HTTPServer.new(
 :Port      => 8443,
 :DocumentRoot  => Dir::pwd + "/htdocs",
 :SSLEnable    => true,
 :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
 :SSLCertificate => @@ssl_cert,
 :SSLPrivateKey  => @@ssl_key
)

Этот пример запускает сервер на порту 8443 таким образом, это не должно работать как корень. :DocumentRoot значение должно содержать путь пустого каталога в каталоге службы профиля.

Необходимо включить SSL и установить значения SSLCertificate и SSLPrivateKey указать на Ваш фактический сертификат SSL и ключ, что Вы получили в Получении сертификата SSL.

Необходимо также отключить клиентскую аутентификацию сертификата, потому что клиентское устройство еще не имеет идентификационных данных поддающихся проверке.

Обработчики службы профиля

После того, как у Вас будет основной веб-сервер, необходимо записать обработчики для нескольких страниц, используемых в процессе регистрации и поставки.

Фаза 1: аутентификация

Страница приветствия (/) Обработчик URL

Страница приветствия является первой страницей, которую видят новые пользователи, когда они вводят сайт на корневом уровне (/). Обработчик для этой страницы показан в Перечислении 2-2.

  Обработчик перечисления 2-2 для / URL

world.mount_proc("/") { |req, res|
  res['Content-Type'] = "text/html"
  res.body = <<WELCOME_MESSAGE
 
<style>
body { margin:40px 40px;font-family:Helvetica;}
h1 { font-size:80px; }
p { font-size:60px; }
a { text-decoration:none; }
</style>
 
<h1 >ACME Inc. Profile Service</h1>
 
<p>If you had to accept the certificate accessing this page, you should
download the <a href="/CA">root certificate</a> and install it so it becomes trusted.
 
<p>We are using a self-signed
certificate here, for production it should be issued by a known CA.
 
<p>After that, go ahead and <a href="/enroll">enroll</a>
 
WELCOME_MESSAGE
 
}

Если Вы использовали самоподписанный сертификат выше, когда пользователь переходит к этой странице, Safari спрашивает, хотите ли Вы доверять сертификату SSL сервера. Принятие позволяет Вам просматривать страницу. Это не достаточно для регистрации, как бы то ни было.

Независимо от того, самоподписывается ли сертификат сайта или нет, процесс регистрации со службой SCEP также требует, чтобы устройство доверяло корневому сертификату пользовательского центра сертификации, что означает добавлять корневой сертификат CA доверяемому списку привязок устройства. Чтобы сделать это, необходимо создать обработчик URL, предоставляющий сертификату корректный тип MIME.

Корневой Сертификат (/CA) Обработчик URL

Ссылка к /CA в странице приветствия предоставляет средние значения пользователю для добавления корневого сертификата пользовательского центра сертификации доверяемому списку привязок устройства. Это требуется для этапа SCEP процесса регистрации.

После того, как Safari на iOS загружает корневой сертификат из того, что URL, это просит у пользователя разрешение добавить новый корневой сертификат доверяемому списку привязок устройства. (Необходимо получить доступ к этой странице только по безопасному соединению.)

Обработчик в Перечислении 2-3 отправляет корневой сертификат.

  Обработчик перечисления 2-3 для /CA URL

world.mount_proc("/CA") { |req, res|
  res['Content-Type'] = "application/x-x509-ca-cert"
  res.body = @@root_cert.to_der
}

После того, как пользователь загрузил корневой сертификат с доверяемого веб-сервера по HTTPS, пользователь может щелкнуть для продолжения процесса регистрации.

Регистрация (/регистрируются), Обработчик URL

Перечисление 2-4 обеспечивает обработчик для /enroll ссылка на странице приветствия.

  Обработчик перечисления 2-4 для /enroll URL

world.mount_proc("/enroll") { |req, res|
  HTTPAuth.basic_auth(req, res, "realm") {|user, password|
    user == 'apple' && password == 'apple'
  }
 
  res['Content-Type'] = "application/x-apple-aspen-config"
  configuration = profile_service_payload(req, "signed-auth-token")
  signed_profile = OpenSSL::PKCS7.sign(@@ssl_cert, @@ssl_key,
      configuration, [], OpenSSL::PKCS7::BINARY)
  res.body = signed_profile.to_der
 
}

Обработчик выше выполняет очень ограниченную аутентификацию для идентификации пользователя. Пользователь входит в систему путем отправки слова apple поскольку имя пользователя и пароль по соединению аутентифицируется с Базовой аутентификацией HTTP. В среде рабочего сервера необходимо вместо этого связать этот код в службу каталогов или некоторую другую систему учетной записи.

Этот обработчик устанавливает тип MIME своего ответа на application/x-apple-aspen-config, таким образом, Safari на iOS обрабатывает ответ как профиль конфигурации.

profile_service_payload функция (Полезная нагрузка Службы Профиля) производит специальную конфигурацию, говорящую телефону регистрировать себя в службе профиля. Литеральная строка "signed-auth-token" должен быть заменен маркером авторизации от услуги аутентификации, проверившей учетные данные пользователя.

Наконец, эта функция подписывает профиль путем вызова OpenSSL::PKCS7.sign и отправляет профиль со знаком в устройство.

Полезная нагрузка службы профиля

Первая полезная нагрузка отправила к устройству (после того, как установление этого, которое позволяется зарегистрировать), полезная нагрузка службы профиля. Эта полезная нагрузка отправляется вызовом в profile_service_payload(req, "signed-auth-token") от /enroll обработчик (Перечисление 2-4).

Для демонстрационной полезной нагрузки службы профиля см. “Демонстрационный Ответ Сервера Фазы 1” в Руководстве по развертыванию Предприятия.

Перечисление 2-5  profile_service_payload функция

def profile_service_payload(request, challenge)
  payload = general_payload()
 
  payload['PayloadType'] = "Profile Service" # do not modify
  payload['PayloadIdentifier'] = "com.acme.mobileconfig.profile-service"
 
  # strings that show up in UI, customisable
  payload['PayloadDisplayName'] = "ACME Profile Service"
  payload['PayloadDescription'] = "Install this profile to enroll for secure access to ACME Inc."
 
  payload_content = Hash.new
  payload_content['URL'] = "https://" + service_address(request) + "/profile"
  payload_content['DeviceAttributes'] = [
    "UDID",
    "VERSION"
=begin
    "PRODUCT",       # e.g. iPhone1,1 or iPod2,1
    "SERIAL",               # The device's serial number
    "MEID",       # The device's Mobile Equipment Identifier
    "IMEI"
=end
    ];
  if (challenge && !challenge.empty?)
    payload_content['Challenge'] = challenge
  end
 
  payload['PayloadContent'] = payload_content
  Plist::Emit.dump(payload)
end

Эта функция запускается путем вызова general_payload, который устанавливает версию, и организация (эти значения не изменяются на данном сервере), и возвращает шаблонную полезную нагрузку, обеспечивающую UUID для профиля.

Содержание полезной нагрузки обеспечивает URL, куда устройство должно отправить свою идентификацию (использующий HTTP POST), вместе со списком атрибутов, которые сервер ожидает, что устройство обеспечит (версия программного обеспечения, IMEI, и т.д.).

Если маркер авторизации (представление аутентификации пользователя) передается в от вызывающей стороны (показанный в Перечислении 2-4), тот маркер добавляется как Challenge атрибут.

В ответ устройство передает список обратно требуемых атрибутов вместе с их значениями. Если сервер отправил a Challenge значение в его запросе, устройство также включает это значение вместе с требуемыми атрибутами устройств. Наконец, для доказательства это - основанное на iOS устройство, устройство подписывает эту идентификацию со своим сертификатом устройства. Этот ответ отправляется в обработчик для /profile URL.

Фаза 2: регистрация сертификата

Запрос профиля (/профиль) Обработчик URL

Обработчик для /profile URL вызывают дважды — один раз для отправки запроса аутентификации устройства, прежде чем устройству позволят зарегистрировать использование SCEP, с другой стороны после шага SCEP для поставки заключительного профиля устройству.

В этом обработчике сервер профиля получает подписанную полезную нагрузку данных PKCS#7 от устройства, которое это тогда распаковывает, и проверяет. Для выборки этого профиля см. “Демонстрационный Ответ Устройства Фазы 2” в Руководстве по развертыванию Предприятия.

Упростить следовать, /profile обработчик разделен на мелкие кусочки. Первая часть этого обработчика показана в Перечислении 2-6.

  Обработчик перечисления 2-6 для /profile URL, часть 1 7

world.mount_proc("/profile") { |req, res|
 
  # verify CMS blob, but don't check signer certificate
  p7sign = OpenSSL::PKCS7::PKCS7.new(req.body)
  store = OpenSSL::X509::Store.new
  p7sign.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY)
  signers = p7sign.signers

Если устройство подписало запрос с сертификатом, принадлежащим иерархии, выпускающей идентификационные данные службы профиля (т.е. если это устройство зарегистрировалось ранее), выполнение следует за первым путем (показанный в Перечислении 2-7). Этот путь или выпускает обновленную зашифрованную конфигурацию или, как реализовано здесь, перенаправляет устройство для регистрации снова. Для тестирования любое устройство, получившее профиль ранее, должно повторно зарегистрироваться.

  Обработчик перечисления 2-7 для /profile URL, часть 2 7

  # this should be checking whether the signer is a cert we issued
  #
  if (signers[0].issuer.to_s == @@root_cert.subject.to_s)
    print "Request from cert with serial #{signers[0].serial}"
      " seen previously: #{@@issued_first_profile.include?(signers[0].serial.to_s)}"
      " (profiles issued to #{@@issued_first_profile.to_a}) \n"
    if (@@issued_first_profile.include?(signers[0].serial.to_s))
     res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, "/enroll")
      print res

Этой точкой любые ранее полностью зарегистрированные клиенты были перенаправлены к странице регистрации для регистрации снова.

Если код заканчивает этот шаг, он получил или список свойств или новый запрос на заключительный профиль.

В Перечислении 2-8 сгенерирован зашифрованный профиль. Поскольку это - часть фазы 3 (конфигурация устройства), это включено здесь без дальнейшего комментария и объяснено далее в Пересмотренном Обработчике профиля/.

  Обработчик перечисления 2-8 для /profile URL, часть 3 7

    else
      @@issued_first_profile.add(signers[0].serial.to_s)
      payload = client_cert_configuration_payload(req)
            # vpn_configuration_payload(req)
 
      #File.open("payload", "w") { |f| f.write payload }
      encrypted_profile = OpenSSL::PKCS7.encrypt(p7sign.certificates,
        payload, OpenSSL::Cipher::Cipher::new("des-ede3-cbc"),
        OpenSSL::PKCS7::BINARY)
      configuration = configuration_payload(req, encrypted_profile.to_der)
    end

Код в Перечислении 2-9 обрабатывает случай, куда устройство отправило свою идентификацию. Эта часть должна идеально проверить, что ответ был подписан с допустимым сертификатом устройства и должен проанализировать атрибуты.

  Обработчик перечисления 2-9 для /profile URL, часть 4 7

  else
    #File.open("signeddata", "w") { |f| f.write p7sign.data }
    device_attributes = Plist::parse_xml(p7sign.data)
    #print device_attributes

Следующий бит кода, Перечисления 2-10, комментируется с =begin и =end. Это показывает, как можно ограничить выпуск профилей к единому устройству (его уникальным устройством ID или UDID) и проверить что Challenge совпадает с Challenge значение вышло ранее.

В продуктивной среде это обычно заменяется специфичным для сайта кодом, запрашивающим службу каталогов для проверки маркера авторизации и запрашивающим базу данных авторизованных значений UDID для устройств, принадлежавших организации.

  Обработчик перечисления 2-10 для /profile URL, часть 5 7

 
=begin
    # Limit issuing of profiles to one device and validate challenge
    if device_attributes['UDID'] == "213cee5cd11778bee2cd1cea624bcc0ab813d235" &&
      device_attributes['CHALLENGE'] == "signed-auth-token"
    end
=end

Затем, отрывок в Перечислении 2-11 получает полезную нагрузку для отправки к устройству, которое скажет его, как завершить процесс регистрации. Подробные данные этой конфигурации описаны в обсуждении encryption_cert_payload.

  Обработчик перечисления 2-11 для /profile URL, часть 6 7

    configuration = encryption_cert_payload(req, "")
  end

Наконец, если эта функция не имеет ничего для отправки, она повышает исключение, делающее сбой запроса HTTP. Иначе это подписывает профиль, который будет отправлен, и возвращает его. Эти биты кода показаны в Перечислении 2-12.

  Обработчик перечисления 2-12 для /profile URL, часть 7 7

  if !configuration || configuration.empty?
    raise "you lose"
  else
   	# we're either sending a configuration to enroll the profile service cert
   	# or a profile specifically for this device
   	res['Content-Type'] = "application/x-apple-aspen-config"
 
    signed_profile = OpenSSL::PKCS7.sign(@@ssl_cert, @@ssl_key,
      configuration, [], OpenSSL::PKCS7::BINARY)
    res.body = signed_profile.to_der
    File.open("profile.der", "w") { |f| f.write signed_profile.to_der }
  end
}

После того, как эта функция отправляет конфигурацию для сообщения устройства, как зарегистрироваться, устройство регистрирует свои идентификационные данные с помощью SCEP. Затем это отправляет запрос для /profile URL связался с этим обработчиком во второй раз для получения заключительного профиля.

Фактическая полезная нагрузка описана в Полезной нагрузке Сертификата Полезной нагрузки и Шифрования Профиля Конфигурации. Для демонстрационного профиля конфигурации см. “Демонстрационный Ответ Сервера Фазы 3 Со Спецификациями SCEP” в Руководстве по развертыванию Предприятия.

Фаза 3: конфигурация устройства

/ профилируют Пересмотренный Обработчик

Ранее, Перечисление 2-8 показало зашифрованный процесс генерации профиля. Рассматриваемый код фактически не работает до фазы 3, однако, таким образом, подробные данные были задержаны. Этот раздел пересматривает тот раздел /profile обработчик и обеспечивает объяснение.

Зашифрованный профиль сгенерирован следующим образом:

  • Конфигурация сгенерирована с рядом полезных нагрузок конфигурации. (См. “Формат Профиля Конфигурации” в Руководстве по развертыванию Предприятия для приобретения знаний о содержании этих полезных нагрузок подробно.)

    В этой ссылочной реализации каждое устройство получает тот же профиль. При желании однако, Challenge информация может использоваться для идентификации пользователя, запрашивающего профиль, и код может генерировать профиль, определенный для того пользователя.

    Точно так же предоставленная информация об устройстве может использоваться для генерации профиля, определенного для данного устройства или определенного типа устройства (например, обеспечивая различный профиль для различных основанных на iOS моделей устройства).

  • Конфигурация шифруется с открытым ключом устройства, подписавшего исходный запрос.

  • Зашифрованный блоб данных обертывается в профиль конфигурации.

Подробные данные этого зашифрованного блоба объяснены в описаниях client_cert_configuration_payload (Перечисление a-1) и configuration_payload (Полезная нагрузка профиля конфигурации).

  Обработчик перечисления 2-13 для /profile URL, часть 3 7 (пересмотренный)

    else
      @@issued_first_profile.add(signers[0].serial.to_s)
      payload = client_cert_configuration_payload(req)
            # vpn_configuration_payload(req)
 
      #File.open("payload", "w") { |f| f.write payload }
      encrypted_profile = OpenSSL::PKCS7.encrypt(p7sign.certificates,
        payload, OpenSSL::Cipher::Cipher::new("des-ede3-cbc"),
        OpenSSL::PKCS7::BINARY)
      configuration = configuration_payload(req, encrypted_profile.to_der)
    end

Полезная нагрузка профиля конфигурации

Полезная нагрузка профиля конфигурации (предоставленный configuration_payload) напоминает полезную нагрузку службы профиля, описанную в Полезной нагрузке Службы Профиля. Единственная разница находится в полезной нагрузке свои переносы.

Для демонстрационного профиля для этой фазы см. “Демонстрационный Ответ Устройства Фазы 4” в Руководстве по развертыванию Предприятия.

Полезная нагрузка сертификата шифрования

Перечисление 2-14 описывает полезную нагрузку сертификата шифрования. Эта полезная нагрузка говорит клиенту, как завершить процесс регистрации.

Перечисление 2-14  encryption_cert_payload функция

def encryption_cert_payload(request, challenge)
  payload = general_payload()
 
  payload['PayloadIdentifier'] = "com.acme.encrypted-profile-service"
  payload['PayloadType'] = "Configuration" # do not modify
 
  # strings that show up in UI, customisable
  payload['PayloadDisplayName'] = "Profile Service Enroll"
  payload['PayloadDescription'] = "Enrolls identity for the encrypted profile service"
 
  payload['PayloadContent'] = [scep_cert_payload(request, "Profile Service", challenge)];
  Plist::Emit.dump(payload)
end

scep_cert_payload функция описана в Полезной нагрузке Сертификата SCEP.

Полезная нагрузка сертификата SCEP

Как имя scep_cert_payload функция предлагает, функция, показанная в Перечислении 2-15, производит полезную нагрузку SCEP, дающую устройству информацию, это должно зарегистрировать сертификат.

Перечисление 2-15  scep_cert_payload функция

def scep_cert_payload(request, purpose, challenge)
  payload = general_payload()
 
  payload['PayloadIdentifier'] = "com.acme.encryption-cert-request"
  payload['PayloadType'] = "com.apple.security.scep" # do not modify

Тип полезной нагрузки com.apple.security.scep указывает полезную нагрузку SCEP, и содержание указывает параметры.  

  # strings that show up in UI, customisable
  payload['PayloadDisplayName'] = purpose
  payload['PayloadDescription'] = "Provides device encryption identity"
 
  payload_content = Hash.new
  payload_content['URL'] = "https://" + service_address(request) + "/scep"

Прежде всего существует базовый URL для службы SCEP, для удобства обрабатывающейся демонстрационной службой также. Это выглядит немного отличающимся для IOS (http://scep-server/cgi-bin/pkiclient.exe) и серверы Windows SCEP (http://scep-server/certsrv/mscep/mscep.dll).  

=begin
  # scep instance NOTE: required for MS SCEP servers
  payload_content['Name'] = ""
=end

Служба может предоставить различные услуги выпуска сертификата, параметризованные на Name значение, становящееся частью заключительного URL. В случае Windows должно быть установлено это значение, несмотря на то, что любое значение сделает.

  payload_content['Subject'] = [ [ [ "O", "ACME Inc." ] ],
    [ [ "CN", purpose + " (" + UUIDTools::UUID.random_create().to_s + ")" ] ] ];
  if (!challenge.empty?)
    payload_content['Challenge'] = challenge
  end

Предмет позволяет клиенту указывать требуемый предмет. В этом случае это заполняется службой профиля. Некоторые службы могут не хотеть предоставлять клиенту возможность указать его и могут использовать Challenge закодировать идентификационные данные запрашивающей стороны.  

Предметы X.509 являются тщательно продуманными структурами и подражаются здесь как массив массивов, чтобы полностью указать его. Каждая пара ключ/значение указана как массив. Ключ является первым элементом и является строкой со значением, которое является любой ID (например, «0.9.2342.19200300.100.1.25» DC), или одно из распознанных сокращений (CN, C, СВ., L, O, OU). Пример выше представляет предмет, который будет часто выводиться на экран как «/O=ACME Inc./CN = {цель} ({случайный UUID})».

  payload_content['Keysize'] = 1024

Затем некоторые, простые параметры, несмотря на то, что они требуют некоторого рассмотрения. Размер ключа запрашивает устройство генерировать пару ключей определенного размера. Только 1024-разрядные и 2048-разрядные размеры ключа должны использоваться. Ключи, больше, чем 2 048 битов, не поддерживаются. В целом 1024-разрядные ключи рекомендуются из-за издержек, вовлеченных в генерацию 2048-разрядных ключей.

  payload_content['Key Type'] = "RSA"

Ключевой тип должен всегда быть RSA, потому что эта ссылочная реализация (и на практике, SCEP) только поддерживают ключи RSA.

  payload_content['Key Usage'] = 5 # digital signature (1) | key encipherment (4)

Ключевое использование указывает цели, для которых ключ может использоваться и является небольшим количеством маски. Бит 0 (оценивают 1) указывает цифровую подпись и кусает 2, указывает ключевую шифровку. Обратите внимание на то, что MS сервер SCEP только выпустит подпись или шифрование, не обоих.

=begin
  payload_content['CAFingerprint'] = StringIO.new(OpenSSL::Digest::SHA1.new(@@root_cert.to_der).digest)
=end

SCEP может работать на основе HTTP, пока свидетельство CA проверяется из полосы. Эта функциональность в настоящее время отключается (как показано выше), потому что iOS в настоящее время не поддерживает это. Эта функция поддерживает такую работу путем добавления цифрового отпечатка к полезной нагрузке SCEP, которую телефон загружает по HTTPS во время регистрации, как показано ниже:

  payload['PayloadContent'] = payload_content;
  payload
end

      payload = client_cert_configuration_payload(req)
            # vpn_configuration_payload(req)