int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, const unsigned char *bytes, int len, int loc, int set) { X509_NAME_ENTRY *ne; int ret; ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); if(!ne) return 0; ret = X509_NAME_add_entry(name, ne, loc, set); X509_NAME_ENTRY_free(ne); return ret; }
X509_NAME * X509_NAME_create_from_txt(const char * n) { // I'm sure there must be a function to do this in OpenSSL, but I'm // darned if I can find it. int idx = 0; int j; bool ok = true; X509_NAME_ENTRY * entries[10]; int entCount = 0; char * name = new char[strlen(n)]; char * value = new char[strlen(n)]; while (true) { while (n[idx] == ' ' || n[idx] == '\t' || n[idx] == '\n' || n[idx] == '\r') idx++; if (n[idx] == 0) break; j = 0; while (n[idx] != 0 && n[idx] != '=') { name[j++] = n[idx++]; } if (j == 0 || n[idx] == 0) { ok = false; break; } name[j] = '\0'; idx++; // Now the value j = 0; while (n[idx] != 0 && n[idx] != '\n' && n[idx] != '\r') { if (n[idx] == ',') { // find out if this is a marker for end of RDN int jdx = idx + 1; while (n[jdx] != '\0' && n[jdx] != '=' && n[jdx] != ',') ++jdx; if (n[jdx] != ',') break; } value[j++] = n[idx++]; } if (j == 0) { ok = false; break; } if (n[idx] != 0) idx++; value[j] = '\0'; X509_NAME_ENTRY * xne; xne = X509_NAME_ENTRY_create_by_txt(NULL, name, MBSTRING_ASC, (unsigned char *) value, -1); if (xne != NULL) { entries[entCount++] = xne; if (entCount == 10) { ok = false; break; } } else { ok = false; break; } } delete[] name; delete[] value; X509_NAME *ret = NULL; int i; if (ok) { // Create the return value ret = X509_NAME_new(); for (i = entCount - 1; i >= 0; --i) { if (!X509_NAME_add_entry(ret, entries[i], -1, 0)) { X509_NAME_free(ret); ret = NULL; break; } } } // Clean out the entries for (i = 0; i < entCount; ++i) { X509_NAME_ENTRY_free(entries[i]); } return ret; }
int openssl_x509_cert() { BIO *b; FILE *fp; RSA *rsa; EVP_PKEY *pkey; X509_NAME *name; const EVP_MD *md; X509_REQ *req, **req2; X509_NAME_ENTRY *entry; unsigned int len; char bytes[COMM_LEN]; const unsigned char *pp; unsigned char *p, *der, *mdout, buf[MAX1_LEN]; OpenSSL_add_all_algorithms(); printf("\nX509_Cert info:\n"); return -1; req = X509_REQ_new(); X509_REQ_set_version(req, 1); name = X509_NAME_new(); strcpy(bytes, "beike"); entry = X509_NAME_ENTRY_create_by_txt(&entry, "commonName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); X509_NAME_add_entry(name, entry, 0, -1); strcpy(bytes, "BEIJING"); entry = X509_NAME_ENTRY_create_by_txt(&entry, "countryName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); X509_NAME_add_entry(name, entry, 1, -1); X509_REQ_set_subject_name(req, name); pkey = EVP_PKEY_new(); rsa = RSA_generate_key(LINE_LEN, RSA_3, NULL, NULL); EVP_PKEY_assign_RSA(pkey, rsa); X509_REQ_set_pubkey(req, pkey); strcpy(bytes, "USTB"); X509_REQ_add1_attr_by_txt(req, "organizationName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); strcpy(bytes, "TECH"); X509_REQ_add1_attr_by_txt(req, "organizationalUnitName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); md = EVP_sha1(); X509_REQ_digest(req, md, mdout, &len); X509_REQ_sign(req, pkey, md); b = BIO_new_file("/tmp/certreq.txt", "w"); PEM_write_bio_X509_REQ(b, req); BIO_free(b); len = i2d_X509_REQ(req, NULL); der = (unsigned char *)malloc(len); p = der; len = i2d_X509_REQ(req, &p); X509_REQ_verify(req, pkey); fp = fopen("/tmp/certder.txt", "wb"); fwrite(der, 1, len, fp); fclose(fp); free(der); X509_REQ_free(req); b = BIO_new_file("/tmp/certreq.txt", "r"); PEM_read_bio_X509_REQ(b, NULL, NULL, NULL); fp = fopen("/tmp/certder.txt", "r"); len = fread(buf, 1, MAX1_LEN, fp); fclose(fp); pp = buf; req2 = (X509_REQ **) malloc(sizeof(X509_REQ *)); d2i_X509_REQ(req2, &pp, len); free(req2); X509_REQ_free(*req2); return 0; }
/** * Check if X509Cert issuer is same as provided issuer name by * http://www.w3.org/TR/xmldsig-core/#dname-encrules which refers to * http://www.ietf.org/rfc/rfc4514.txt * * String X.500 AttributeType * CN commonName (2.5.4.3) * L localityName (2.5.4.7) * ST stateOrProvinceName (2.5.4.8) * O organizationName (2.5.4.10) * OU organizationalUnitName (2.5.4.11) * C countryName (2.5.4.6) * STREET streetAddress (2.5.4.9) * DC domainComponent (0.9.2342.19200300.100.1.25) * UID userId (0.9.2342.19200300.100.1.1) * * These attribute types are described in [RFC4519]. * Implementations MAY recognize other DN string representations. * However, as there is no requirement that alternative DN string * representations be recognized (and, if so, how), implementations * SHOULD only generate DN strings in accordance with Section 2 of this document. * * @param issuer name * @return 0 if equal, otherwise a number different from 0 is returned * @throw IOException if error */ int digidoc::X509Cert::compareIssuerToString(const std::string &name) const throw(IOException) { size_t pos = 0, old = 0; while(true) { pos = name.find(",", old); if(pos == std::string::npos) { pos = name.size(); if(pos < old) break; } else { if(name.compare(pos-1, 1, "\\") == 0) continue; } std::string nameitem = name.substr(old, pos - old); old = pos + 1; if((pos = nameitem.find("=")) == std::string::npos || nameitem.compare(pos-1, 1, "\\") == 0) continue; std::string obj = nameitem.substr(0, pos); if(obj.compare("CN") != 0 && obj.compare("commonName") != 0 && obj.compare("L") != 0 && obj.compare("localityName") != 0 && obj.compare("ST") != 0 && obj.compare("stateOrProvinceName") != 0 && obj.compare("O") != 0 && obj.compare("organizationName") != 0 && obj.compare("OU") != 0 && obj.compare("organizationalUnitName") != 0 && obj.compare("C" ) != 0 && obj.compare("countryName") != 0 && obj.compare("STREET") != 0 && obj.compare("streetAddress") != 0 && obj.compare("DC") != 0 && obj.compare("domainComponent") != 0 && obj.compare("UID") != 0 && obj.compare("userId") != 0) continue; X509_NAME_ENTRY *enta = X509_NAME_ENTRY_create_by_txt(0, obj.c_str(), MBSTRING_UTF8, (unsigned char*)nameitem.substr(pos+1, pos-old).c_str(), -1); if(!enta) return -1; ASN1_OBJECT *obja = X509_NAME_ENTRY_get_object(enta); bool found = false; for(int i = 0; i < X509_NAME_entry_count(getIssuerNameAsn1()); ++i) { X509_NAME_ENTRY *entb = X509_NAME_get_entry(getIssuerNameAsn1(), i); ASN1_OBJECT *objb = X509_NAME_ENTRY_get_object(entb); if(memcmp(obja->data, objb->data, obja->length) == 0 && memcmp(enta->value, entb->value, enta->size) == 0) { found = true; break; } } X509_NAME_ENTRY_free(enta); if(!found) return -1; } return 0; }