класс OpenSSL::Netscape::SPKI
Реализация простого протокола инфраструктуры открытых ключей (произносится «споки»). Структура определяется как
PublicKeyAndChallenge ::= SEQUENCE {
spki SubjectPublicKeyInfo,
challenge IA5STRING
}
SignedPublicKeyAndChallenge ::= SEQUENCE {
publicKeyAndChallenge PublicKeyAndChallenge,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING
} где определения SubjectPublicKeyInfo и AlgorithmIdentifier можно найти в RFC5280. SPKI обычно используется в браузерах для создания пары открытый/закрытый ключ и последующего запроса сертификата, используя элемент HTML <keygen>.
Примеры
Создание SPKI
key = OpenSSL::PKey::RSA.new 2048
spki = OpenSSL::Netscape::SPKI.new
spki.challenge = "RandomChallenge"
spki.public_key = key.public_key
spki.sign(key, OpenSSL::Digest.new('SHA256'))
#send a request containing this to a server generating a certificate
Проверка запроса SPKI
request = #... spki = OpenSSL::Netscape::SPKI.new request unless spki.verify(spki.public_key) # signature is invalid end #proceed
Публичные методы класса
static VALUE
ossl_spki_initialize(int argc, VALUE *argv, VALUE self)
{
NETSCAPE_SPKI *spki;
VALUE buffer;
const unsigned char *p;
if (rb_scan_args(argc, argv, "01", &buffer) == 0) {
return self;
}
StringValue(buffer);
if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), RSTRING_LENINT(buffer)))) {
ossl_clear_error();
p = (unsigned char *)RSTRING_PTR(buffer);
if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) {
ossl_raise(eSPKIError, NULL);
}
}
NETSCAPE_SPKI_free(DATA_PTR(self));
SetSPKI(self, spki);
return self;
} Параметры
-
request - необязательный исходный запрос в формате PEM или DER.
Публичные методы экземпляра
static VALUE
ossl_spki_get_challenge(VALUE self)
{
NETSCAPE_SPKI *spki;
GetSPKI(self, spki);
if (spki->spkac->challenge->length <= 0) {
OSSL_Debug("Challenge.length <= 0?");
return rb_str_new(0, 0);
}
return rb_str_new((const char *)spki->spkac->challenge->data,
spki->spkac->challenge->length);
} Возвращает строку вызова, связанную с этим SPKI.
static VALUE
ossl_spki_set_challenge(VALUE self, VALUE str)
{
NETSCAPE_SPKI *spki;
StringValue(str);
GetSPKI(self, spki);
if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str),
RSTRING_LENINT(str))) {
ossl_raise(eSPKIError, NULL);
}
return str;
} Параметры
-
str - строка вызова, которая должна быть установлена для этого экземпляра
Устанавливает вызов, который будет связан с SPKI. Может использоваться сервером, например, для предотвращения повторных запросов.
static VALUE
ossl_spki_get_public_key(VALUE self)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
GetSPKI(self, spki);
if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */
ossl_raise(eSPKIError, NULL);
}
return ossl_pkey_new(pkey); /* NO DUP - OK */
} Возвращает открытый ключ, связанный с SPKI, экземпляр OpenSSL::PKey.
static VALUE
ossl_spki_set_public_key(VALUE self, VALUE key)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
GetSPKI(self, spki);
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
if (!NETSCAPE_SPKI_set_pubkey(spki, pkey))
ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey");
return key;
} Параметры
-
pub - открытый ключ, который должен быть установлен для этого экземпляра
Устанавливает открытый ключ, который будет связан с SPKI, экземпляр OpenSSL::PKey. Это должен быть открытый ключ, соответствующий закрытому ключу, используемому для подписи SPKI.
static VALUE
ossl_spki_sign(VALUE self, VALUE key, VALUE digest)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
const EVP_MD *md;
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
md = ossl_evp_get_digestbyname(digest);
GetSPKI(self, spki);
if (!NETSCAPE_SPKI_sign(spki, pkey, md)) {
ossl_raise(eSPKIError, NULL);
}
return self;
} Параметры
-
key - закрытый ключ, который будет использоваться для подписи этого экземпляра
-
digest - хеш-код, который будет использоваться для подписи этого экземпляра
Для подписи SPKI должен использоваться закрытый ключ, соответствующий установленному открытому ключу для этого экземпляра, а также алгоритм хеширования в виде OpenSSL::Digest. Закрытый ключ должен быть экземпляром OpenSSL::PKey.
static VALUE
ossl_spki_to_der(VALUE self)
{
NETSCAPE_SPKI *spki;
VALUE str;
long len;
unsigned char *p;
GetSPKI(self, spki);
if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0)
ossl_raise(eX509CertError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if (i2d_NETSCAPE_SPKI(spki, &p) <= 0)
ossl_raise(eX509CertError, NULL);
ossl_str_adjust(str, p);
return str;
} Возвращает кодировку DER этого SPKI.
static VALUE
ossl_spki_to_pem(VALUE self)
{
NETSCAPE_SPKI *spki;
char *data;
VALUE str;
GetSPKI(self, spki);
if (!(data = NETSCAPE_SPKI_b64_encode(spki))) {
ossl_raise(eSPKIError, NULL);
}
str = ossl_buf2str(data, rb_long2int(strlen(data)));
return str;
} Возвращает кодировку PEM этого SPKI.
static VALUE
ossl_spki_print(VALUE self)
{
NETSCAPE_SPKI *spki;
BIO *out;
GetSPKI(self, spki);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eSPKIError, NULL);
}
if (!NETSCAPE_SPKI_print(out, spki)) {
BIO_free(out);
ossl_raise(eSPKIError, NULL);
}
return ossl_membio2str(out);
} Возвращает текстовое представление этого SPKI, полезное для отладки.
static VALUE
ossl_spki_verify(VALUE self, VALUE key)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
GetSPKI(self, spki);
pkey = GetPKeyPtr(key);
ossl_pkey_check_public_key(pkey);
switch (NETSCAPE_SPKI_verify(spki, pkey)) {
case 0:
ossl_clear_error();
return Qfalse;
case 1:
return Qtrue;
default:
ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify");
}
} Параметры
-
key - открытый ключ, который будет использоваться для проверки подписи
SPKI
Возвращает true если подпись действительна, false в противном случае. Для проверки SPKI следует использовать открытый ключ, содержащийся в SPKI.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.