/** * @see shsig_shr_verify() */ static int _shcert_sign_verify_shr(shcert_t *cert, shcert_t *parent) { shkey_t *key; unsigned char *enc_data; size_t enc_len; int err; if (!parent) return (SHERR_INVAL); err = shencode((char *)&parent->cert_sub.ent_sig.sig_key, sizeof(shkey_t), &enc_data, &enc_len, &parent->cert_iss.ent_sig.sig_key); if (err) return (err); key = shkey_bin(enc_data, enc_len); free(enc_data); if (!shkey_cmp(key, &cert->cert_sub.ent_sig.sig_key)) { /* encrypted key is not validated. */ shkey_free(&key); return (SHERR_KEYREJECTED); } shkey_free(&key); return (0); }
static int _lfunc_sexe_shencode(lua_State *L) { const char *raw_str = luaL_checkstring(L, 1); const char *key_str = luaL_checkstring(L, 2); unsigned char *data; size_t data_len; shkey_t *key; int err; if (!raw_str) raw_str = ""; key = shkey_gen(key_str); err = shencode(raw_str, strlen(raw_str), &data, &data_len, key); shkey_free(&key); if (err) { lua_pushnil(L); return (1); /* (1) nil */ } lua_pushlstring(L, data, data_len); free(data); return (1); /* (1) encoded string */ }
/** * @see shsig_shr_sign() */ int shcert_sign(shcert_t *cert, shcert_t *parent) { shkey_t *key; unsigned char *enc_data; size_t enc_len; int err; if (!parent) return (SHERR_INVAL); if (!(parent->cert_flag & SHCERT_CERT_SIGN)) { /* parent certificate lacks ability to sign. */ return (SHERR_INVAL); } /* assign issuer's 128-bit serial number (regardless of algorythm) */ memcpy(cert->cert_iss.ent_ser, parent->cert_sub.ent_ser, 16); if (cert->cert_sub.ent_sig.sig_key.alg == SHKEY_ALG_ECDSA) { shkey_t *pub_key = &cert->cert_sub.ent_sig.sig_key; shkey_t *priv_key; shkey_t *seed_key; shpeer_t *peer; char sig_r[256]; char sig_s[256]; char *hex_data; unsigned char data[256]; int data_len; /* fill in parent signature */ memcpy(&cert->cert_iss.ent_sig, &parent->cert_sub.ent_sig, sizeof(shsig_t)); peer = shpeer_init(NULL, NULL); seed_key = shpeer_kpriv(peer); priv_key = shecdsa_key_priv(shkey_hex(seed_key)); shpeer_free(&peer); pub_key = shecdsa_key_pub(priv_key); memcpy(&cert->cert_sub.ent_sig.sig_key, pub_key, sizeof(shkey_t)); if ((parent->cert_flag & SHCERT_CERT_NONREPUDIATION)) { /* must be derived from owner to preserve authenticy. */ if (!shkey_cmp(&cert->cert_sub.ent_sig.sig_key, &cert->cert_iss.ent_sig.sig_key)) { return (SHERR_ACCESS); } } hex_data = shkey_hex(&cert->cert_iss.ent_sig.sig_key); data_len = strlen(hex_data) / 2; memset(data, 0, sizeof(data)); hex2bin(data, hex_data, data_len); shecdsa_sign(priv_key, sig_r, sig_s, data, data_len); strcpy(cert->cert_sub.ent_sig.key.ecdsa.sig_r, sig_r); strcpy(cert->cert_sub.ent_sig.key.ecdsa.sig_s, sig_s); cert->cert_sub.ent_len = data_len; shkey_free(&pub_key); shkey_free(&priv_key); } else { err = shencode((char *)&parent->cert_sub.ent_sig.sig_key, sizeof(shkey_t), &enc_data, &enc_len, &parent->cert_iss.ent_sig.sig_key); if (err) return (err); key = shkey_bin(enc_data, enc_len); free(enc_data); memcpy(&cert->cert_sub.ent_sig.sig_key, key, sizeof(shkey_t)); cert->cert_sub.ent_len = enc_len; shkey_free(&key); } cert->cert_flag |= SHCERT_CERT_CHAIN; cert->cert_flag |= parent->cert_flag; /* inherit parent's attributes */ cert->cert_sub.ent_sig.sig_key.alg = parent->cert_sub.ent_sig.sig_key.alg; strcpy(cert->cert_iss.ent_name, parent->cert_sub.ent_name); cert->cert_iss.ent_sig.sig_stamp = parent->cert_sub.ent_sig.sig_stamp; cert->cert_iss.ent_sig.sig_expire = parent->cert_sub.ent_sig.sig_expire; cert->cert_iss.ent_len = parent->cert_sub.ent_len; return (0); }