class OpenSSL::Netscape::SPKI
一种简单的公钥基础设施实现(发音为“spooky”)。结构定义为
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
公共类方法
                         new([request]) → spki  点击以切换源代码
                            参数¶ ↑
- 
request - 可选的原始请求,可以是 PEM 或 DER 格式。 
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;
}
                              公共实例方法
                         challenge → string  点击以切换源代码
                            返回与此 SPKI 关联的质询字符串。
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);
}
                              
                         challenge = str → string  点击以切换源代码
                            参数¶ ↑
- 
str - 要为此实例设置的质询字符串 
设置要与 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;
}
                              
                         public_key → pkey  点击以切换源代码
                            返回与 SPKI 关联的公钥,它是 OpenSSL::PKey 的一个实例。
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 */
}
                              
                         public_key = pub → pkey  点击以切换源代码
                            参数¶ ↑
- 
pub - 要为此实例设置的公钥 
设置要与 SPKI 关联的公钥,它是 OpenSSL::PKey 的一个实例。这应该是与用于签署 SPKI 的私钥相对应的公钥。
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;
}
                              
                         sign(key, digest) → spki  点击以切换源代码
                            参数¶ ↑
- 
key - 用于签署此实例的私钥 
- 
digest - 用于签署此实例的摘要算法 
要签署 SPKI,应使用与为此实例设置的公钥相对应的私钥,以及 OpenSSL::Digest 形式的摘要算法。私钥应该是 OpenSSL::PKey 的一个实例。
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;
}
                              
                         to_der → DER 编码的字符串  点击以切换源代码
                            返回此 SPKI 的 DER 编码。
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(eSPKIError, "i2d_NETSCAPE_SPKI");
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if (i2d_NETSCAPE_SPKI(spki, &p) <= 0)
        ossl_raise(eSPKIError, "i2d_NETSCAPE_SPKI");
    ossl_str_adjust(str, p);
    return str;
}
                              
                         to_pem → PEM 编码的字符串  点击以切换源代码
                            返回此 SPKI 的 PEM 编码。
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;
}
                              也别名为: to_s
                          
                         to_text → string  点击以切换源代码
                            返回此 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);
}
                              
                         verify(key) → boolean  点击以切换源代码
                            参数¶ ↑
- 
key - 用于验证 SPKI签名的公钥
如果签名有效,则返回 true,否则返回 false。要验证 SPKI,应使用 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");
    }
}