//Get key from a binary key xmlSecKey* get_key_from_keystr(const std::string& value) {//, const bool usage) { xmlSecKey *key = NULL; xmlSecKeyDataFormat key_formats[] = { xmlSecKeyDataFormatDer, xmlSecKeyDataFormatCertDer, xmlSecKeyDataFormatPkcs8Der, xmlSecKeyDataFormatCertPem, xmlSecKeyDataFormatPkcs8Pem, xmlSecKeyDataFormatPem, xmlSecKeyDataFormatBinary, (xmlSecKeyDataFormat)0 }; int rc; //We need to remove the "BEGIN RSA PRIVATE KEY" and "END RSA PRIVATE KEY" //if they exit in the input parameter std::string v; std::size_t pos1, pos2; pos1 = value.find("BEGIN RSA PRIVATE KEY"); if(pos1 == std::string::npos) { pos1 = value.find("BEGIN RSA PUBLIC KEY"); } if(pos1 != std::string::npos) { pos1 = pos1 + 21; pos2 = value.find_first_not_of("-", pos1); v = value.substr(pos2); pos2 = v.find_first_of("-"); v.resize(pos2); } else v = value; xmlSecErrorsDefaultCallbackEnableOutput(FALSE); xmlSecByte* tmp_str = new xmlSecByte[v.size()]; memset(tmp_str,0,v.size()); rc = xmlSecBase64Decode((const xmlChar*)(v.c_str()), tmp_str, v.size()); if (rc < 0) { //bad base-64 memcpy(tmp_str,v.c_str(),v.size()); rc = v.size(); } for (int i=0; key_formats[i] && key == NULL; i++) { key = xmlSecCryptoAppKeyLoadMemory(tmp_str, rc, key_formats[i], NULL, NULL, NULL); } delete[] tmp_str; xmlSecErrorsDefaultCallbackEnableOutput(TRUE); return key; }
int verify_document(xmlDocPtr doc, const char* key) { initialize(); xmlNodePtr node = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; int res = 0; if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)){ rb_raise(rb_eRuntimeError, "unable to parse XML document"); } /* find start node */ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs); if(node == NULL) { rb_raise(rb_eRuntimeError, "could not find start node in XML document"); } if(assign_id_attributes(doc) < 0) { rb_raise(rb_eRuntimeError, "Could not find ID attribute in document"); } /* create signature context */ dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { cleanup(dsigCtx); rb_raise(rb_eRuntimeError, "could not create signature context"); } /* load public key */ dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory(key, strlen(key), xmlSecKeyDataFormatCertPem, NULL, NULL, NULL); if(dsigCtx->signKey == NULL) { cleanup(dsigCtx); rb_raise(rb_eRuntimeError, "could not read public pem key %s", key); } /* Verify signature */ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) { cleanup(dsigCtx); rb_raise(rb_eRuntimeError, "Document does not seem to be in an XMLDsig format"); } /* print verification result to stdout */ if(dsigCtx->status == xmlSecDSigStatusSucceeded) { res = 1; } else { res = 0; } cleanup(dsigCtx); return res; }
static int addRubyKeyToManager(VALUE rb_key, VALUE rb_value, VALUE rb_manager) { xmlSecKeysMngrPtr keyManager = (xmlSecKeysMngrPtr)rb_manager; char *keyName, *keyData; unsigned int keyDataLength; xmlSecKeyPtr key; Check_Type(rb_key, T_STRING); Check_Type(rb_value, T_STRING); keyName = RSTRING_PTR(rb_key); keyData = RSTRING_PTR(rb_value); keyDataLength = RSTRING_LEN(rb_value); // load key key = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)keyData, keyDataLength, xmlSecKeyDataFormatPem, NULL, // password NULL, NULL); if (key == NULL) { rb_warn("failed to load '%s' public or private pem key", keyName); return ST_CONTINUE; } // set key name if (xmlSecKeySetName(key, BAD_CAST keyName) < 0) { rb_warn("failed to set key name for key '%s'", keyName); return ST_CONTINUE; } // add key to key manager; from now on the manager is responsible for // destroying the key if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(keyManager, key) < 0) { rb_warn("failed to add key '%s' to key manager", keyName); return ST_CONTINUE; } return ST_CONTINUE; }
xmlSecKeysMngrPtr load_certificates_sign(opendcp_t *opendcp) { xmlSecKeysMngrPtr key_manager; xmlSecKeyPtr key; /* create and initialize keys manager */ key_manager = xmlSecKeysMngrCreate(); if (key_manager == NULL) { fprintf(stderr, "Error: failed to create keys manager.\n"); return(NULL); } if (xmlSecCryptoAppDefaultKeysMngrInit(key_manager) < 0) { fprintf(stderr, "Error: failed to initialize keys manager.\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } /* read key file */ if (opendcp->xml_signature.private_key) { key = xmlSecCryptoAppKeyLoad(opendcp->xml_signature.private_key, xmlSecKeyDataFormatPem, NULL, NULL, NULL); } else { key = xmlSecCryptoAppKeyLoadMemory(opendcp_private_key, strlen((char *)opendcp_private_key),xmlSecKeyDataFormatPem, NULL, NULL, NULL); } if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(key_manager, key) < 0) { fprintf(stderr, "Error: failed to initialize keys manager.\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } /* load root certificate */ if (opendcp->xml_signature.root) { if (xmlSecCryptoAppKeysMngrCertLoad(key_manager, opendcp->xml_signature.root, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", opendcp->xml_signature.root); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } else { if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, opendcp_root_cert, strlen((char* )opendcp_root_cert), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate from memory\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } /* load ca (intermediate) certificate */ if (opendcp->xml_signature.ca) { if (xmlSecCryptoAppKeysMngrCertLoad(key_manager, opendcp->xml_signature.ca, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate \"%s\"\n", opendcp->xml_signature.ca); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } else { if (xmlSecCryptoAppKeysMngrCertLoadMemory(key_manager, opendcp_ca_cert, strlen((char *)opendcp_ca_cert), xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) { fprintf(stderr,"Error: failed to load pem certificate from memory\n"); xmlSecKeysMngrDestroy(key_manager); return(NULL); } } return(key_manager); }
VALUE sign_with_certificate(VALUE self, VALUE rb_key_name, VALUE rb_rsa_key, VALUE rb_cert) { xmlDocPtr doc; xmlNodePtr signNode = NULL; xmlNodePtr refNode = NULL; xmlNodePtr keyInfoNode = NULL; xmlSecDSigCtxPtr dsigCtx = NULL; char *keyName; char *certificate; char *rsaKey; unsigned int rsaKeyLength, certificateLength; Data_Get_Struct(self, xmlDoc, doc); rsaKey = RSTRING_PTR(rb_rsa_key); rsaKeyLength = RSTRING_LEN(rb_rsa_key); keyName = RSTRING_PTR(rb_key_name); certificate = RSTRING_PTR(rb_cert); certificateLength = RSTRING_LEN(rb_cert); // create signature template for RSA-SHA1 enveloped signature signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId, xmlSecTransformRsaSha1Id, NULL); if (signNode == NULL) { rb_raise(rb_eSigningError, "failed to create signature template"); goto done; } // add <dsig:Signature/> node to the doc xmlAddChild(xmlDocGetRootElement(doc), signNode); // add reference refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id, NULL, NULL, NULL); if(refNode == NULL) { rb_raise(rb_eSigningError, "failed to add reference to signature template"); goto done; } // add enveloped transform if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) { rb_raise(rb_eSigningError, "failed to add enveloped transform to reference"); goto done; } // add <dsig:KeyInfo/> and <dsig:X509Data/> keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL); if(keyInfoNode == NULL) { rb_raise(rb_eSigningError, "failed to add key info"); goto done; } if(xmlSecTmplKeyInfoAddX509Data(keyInfoNode) == NULL) { rb_raise(rb_eSigningError, "failed to add X509Data node"); goto done; } // create signature context, we don't need keys manager in this example dsigCtx = xmlSecDSigCtxCreate(NULL); if(dsigCtx == NULL) { rb_raise(rb_eSigningError, "failed to create signature context"); goto done; } // load private key, assuming that there is not password dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey, rsaKeyLength, xmlSecKeyDataFormatPem, NULL, // password NULL, NULL); if(dsigCtx->signKey == NULL) { rb_raise(rb_eSigningError, "failed to load private key"); goto done; } // load certificate and add to the key if(xmlSecCryptoAppKeyCertLoadMemory(dsigCtx->signKey, (xmlSecByte *)certificate, certificateLength, xmlSecKeyDataFormatPem) < 0) { rb_raise(rb_eSigningError, "failed to load certificate"); goto done; } // set key name if(xmlSecKeySetName(dsigCtx->signKey, (xmlSecByte *)keyName) < 0) { rb_raise(rb_eSigningError, "failed to set key name"); goto done; } // sign the template if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) { rb_raise(rb_eSigningError, "signature failed"); goto done; } done: if(dsigCtx != NULL) { xmlSecDSigCtxDestroy(dsigCtx); } return T_NIL; }