static int xmlSecOpenSSLEvpSignatureSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecOpenSSLEvpSignatureCtxPtr ctx; xmlSecKeyDataPtr value; EVP_PKEY* pKey; xmlSecAssert2(xmlSecOpenSSLEvpSignatureCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpSignatureSize), -1); xmlSecAssert2(key != NULL, -1); ctx = xmlSecOpenSSLEvpSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digest != NULL, -1); xmlSecAssert2(ctx->keyId != NULL, -1); xmlSecAssert2(xmlSecKeyCheckId(key, ctx->keyId), -1); value = xmlSecKeyGetValue(key); xmlSecAssert2(value != NULL, -1); pKey = xmlSecOpenSSLEvpKeyDataGetEvp(value); if(pKey == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecOpenSSLEvpKeyDataGetEvp", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } if(ctx->pKey != NULL) { EVP_PKEY_free(ctx->pKey); } ctx->pKey = xmlSecOpenSSLEvpKeyDup(pKey); if(ctx->pKey == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecOpenSSLEvpKeyDup", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(0); }
static int xmlSecGCryptKWAesInitialize(xmlSecTransformPtr transform) { xmlSecGCryptKWAesCtxPtr ctx; int ret; xmlSecAssert2(xmlSecGCryptKWAesCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptKWAesSize), -1); ctx = xmlSecGCryptKWAesGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformKWAes128Id)) { ctx->cipher = GCRY_CIPHER_AES128; ctx->keyExpectedSize = XMLSEC_KW_AES128_KEY_SIZE; } else if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformKWAes192Id)) { ctx->cipher = GCRY_CIPHER_AES192; ctx->keyExpectedSize = XMLSEC_KW_AES192_KEY_SIZE; } else if(xmlSecTransformCheckId(transform, xmlSecGCryptTransformKWAes256Id)) { ctx->cipher = GCRY_CIPHER_AES256; ctx->keyExpectedSize = XMLSEC_KW_AES256_KEY_SIZE; } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_TRANSFORM, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ctx->mode = GCRY_CIPHER_MODE_CBC; ctx->flags = GCRY_CIPHER_SECURE; /* we are paranoid */ ctx->blockSize = gcry_cipher_get_algo_blklen(ctx->cipher); xmlSecAssert2(ctx->blockSize > 0, -1); ret = xmlSecBufferInitialize(&(ctx->keyBuffer), 0); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecGCryptKWAesGetKey", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(0); }
/** * xmlSecKeyReadMemory: * @dataId: the key value data klass. * @data: the memory containing the key * @dataSize: the size of the memory block * * Reads the key value of klass @dataId from a memory block @data. * * Returns: pointer to newly created key or NULL if an error occurs. */ xmlSecKeyPtr xmlSecKeyReadMemory(xmlSecKeyDataId dataId, const xmlSecByte* data, xmlSecSize dataSize) { xmlSecBuffer buffer; xmlSecKeyPtr key; int ret; xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL); xmlSecAssert2(data != NULL, NULL); xmlSecAssert2(dataSize > 0, NULL); /* read file to buffer */ ret = xmlSecBufferInitialize(&buffer, 0); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)), "xmlSecBufferInitialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(NULL); } if (xmlSecBufferAppend(&buffer, data, dataSize) < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)), "xmlSecBufferAppend", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecBufferFinalize(&buffer); return(NULL); } key = xmlSecKeyReadBuffer(dataId, &buffer); if(key == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId)), "xmlSecKeyReadBuffer", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecBufferFinalize(&buffer); return(NULL); } xmlSecBufferFinalize(&buffer); return (key); }
static int xmlSecGCryptKWAesSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecGCryptKWAesCtxPtr ctx; xmlSecBufferPtr buffer; xmlSecSize keySize; int ret; xmlSecAssert2(xmlSecGCryptKWAesCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptKWAesSize), -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecGCryptKeyDataAesId), -1); ctx = xmlSecGCryptKWAesGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key)); xmlSecAssert2(buffer != NULL, -1); keySize = xmlSecBufferGetSize(buffer); if(keySize < ctx->keyExpectedSize) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, "key=%d;expected=%d", keySize, ctx->keyExpectedSize); return(-1); } ret = xmlSecBufferSetData(&(ctx->keyBuffer), xmlSecBufferGetData(buffer), ctx->keyExpectedSize); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetData", XMLSEC_ERRORS_R_XMLSEC_FAILED, "expected-size=%d", ctx->keyExpectedSize); return(-1); } return(0); }
static int xmlSecOpenSSLRsaOaepNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLRsaOaepCtxPtr ctx; xmlNodePtr cur; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1); xmlSecAssert2(node != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLRsaOaepGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(xmlSecBufferGetSize(&(ctx->oaepParams)) == 0, -1); cur = xmlSecGetNextElementNode(node->children); while(cur != NULL) { if(xmlSecCheckNodeName(cur, xmlSecNodeRsaOAEPparams, xmlSecEncNs)) { ret = xmlSecBufferBase64NodeContentRead(&(ctx->oaepParams), cur); if(ret < 0) { xmlSecInternalError("xmlSecBufferBase64NodeContentRead", xmlSecTransformGetName(transform)); return(-1); } } else if(xmlSecCheckNodeName(cur, xmlSecNodeDigestMethod, xmlSecDSigNs)) { xmlChar* algorithm; /* Algorithm attribute is required */ algorithm = xmlGetProp(cur, xmlSecAttrAlgorithm); if(algorithm == NULL) { xmlSecInvalidNodeAttributeError(cur, xmlSecAttrAlgorithm, xmlSecTransformGetName(transform), "empty"); return(-1); } /* for now we support only sha1 */ if(xmlStrcmp(algorithm, xmlSecHrefSha1) != 0) { xmlSecInvalidTransfromError2(transform, "digest algorithm=\"%s\" is not supported for rsa/oaep", xmlSecErrorsSafeString(algorithm)); xmlFree(algorithm); return(-1); } xmlFree(algorithm); } else { /* not found */ xmlSecUnexpectedNodeError(cur, xmlSecTransformGetName(transform)); return(-1); } /* next node */ cur = xmlSecGetNextElementNode(cur->next); } return(0); }
static int xmlSecOpenSSLRsaOaepExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLRsaOaepCtxPtr ctx; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLRsaOaepGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pKey != NULL, -1); if(transform->status == xmlSecTransformStatusNone) { transform->status = xmlSecTransformStatusWorking; } if((transform->status == xmlSecTransformStatusWorking) && (last == 0)) { /* just do nothing */ } else if((transform->status == xmlSecTransformStatusWorking) && (last != 0)) { ret = xmlSecOpenSSLRsaOaepProcess(transform, transformCtx); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecOpenSSLRsaOaepProcess", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } transform->status = xmlSecTransformStatusFinished; } else if(transform->status == xmlSecTransformStatusFinished) { /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_STATUS, "status=%d", transform->status); return(-1); } return(0); }
static int xmlSecGCryptHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecGCryptHmacCtxPtr ctx; xmlSecKeyDataPtr value; xmlSecBufferPtr buffer; gcry_error_t err; xmlSecAssert2(xmlSecGCryptHmacCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptHmacSize), -1); xmlSecAssert2(key != NULL, -1); ctx = xmlSecGCryptHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digestCtx != NULL, -1); value = xmlSecKeyGetValue(key); xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecGCryptKeyDataHmacId), -1); buffer = xmlSecKeyDataBinaryValueGetBuffer(value); xmlSecAssert2(buffer != NULL, -1); if(xmlSecBufferGetSize(buffer) == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, "key is empty"); return(-1); } err = gcry_md_setkey(ctx->digestCtx, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer)); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "gcry_md_setkey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } return(0); }
static int xmlSecTransformVisa3DHackExecute(xmlSecTransformPtr transform, int last, xmlSecTransformCtxPtr transformCtx) { xmlChar** idPtr; xmlDocPtr doc; xmlAttrPtr attr; xmlNodeSetPtr nodeSet; xmlSecAssert2(xmlSecTransformVisa3DHackCheckId(transform), -1); xmlSecAssert2(transform->outNodes == NULL, -1); xmlSecAssert2(last != 0, -1); xmlSecAssert2(transformCtx != NULL, -1); idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform); xmlSecAssert2(idPtr != NULL, -1); xmlSecAssert2((*idPtr) != NULL, -1); doc = (transform->inNodes != NULL) ? transform->inNodes->doc : transform->hereNode->doc; xmlSecAssert2(doc != NULL, -1); attr = xmlGetID(doc, (*idPtr)); if((attr == NULL) || (attr->parent == NULL)) { xmlSecXmlError2("xmlGetID", xmlSecTransformGetName(transform), "id=\"%s\"", xmlSecErrorsSafeString(*idPtr)); return(-1); } nodeSet = xmlXPathNodeSetCreate(attr->parent); if(nodeSet == NULL) { xmlSecXmlError2("xmlXPathNodeSetCreate", xmlSecTransformGetName(transform), "id=\"%s\"", xmlSecErrorsSafeString(*idPtr)); return(-1); } transform->outNodes = xmlSecNodeSetCreate(doc, nodeSet, xmlSecNodeSetTreeWithoutComments); if(transform->outNodes == NULL) { xmlSecInternalError("xmlSecNodeSetCreate", xmlSecTransformGetName(transform)); xmlXPathFreeNodeSet(nodeSet); return(-1); } return(0); }
static int xmlSecMSCryptoDigestVerify(xmlSecTransformPtr transform, const xmlSecByte* data, xmlSecSize dataSize, xmlSecTransformCtxPtr transformCtx) { xmlSecMSCryptoDigestCtxPtr ctx; xmlSecAssert2(xmlSecMSCryptoDigestCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoDigestSize), -1); xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1); xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1); xmlSecAssert2(data != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecMSCryptoDigestGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->dgstSize > 0, -1); if(dataSize != ctx->dgstSize) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_SIZE, "data_size=%d;dgst_size=%d", dataSize, ctx->dgstSize); transform->status = xmlSecTransformStatusFail; return(0); } if(memcmp(ctx->dgst, data, ctx->dgstSize) != 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_DATA, "data and digest do not match"); transform->status = xmlSecTransformStatusFail; return(0); } transform->status = xmlSecTransformStatusOk; return(0); }
/** * xmlSecPtrListCopy: * @dst: the pointer to destination list. * @src: the pointer to source list. * * Copies @src list items to @dst list using #duplicateItem method * of the list klass. If #duplicateItem method is NULL then * we jsut copy pointers to items. * * Returns 0 on success or a negative value if an error occurs. */ int xmlSecPtrListCopy(xmlSecPtrListPtr dst, xmlSecPtrListPtr src) { xmlSecSize i; int ret; xmlSecAssert2(xmlSecPtrListIsValid(dst), -1); xmlSecAssert2(xmlSecPtrListIsValid(src), -1); xmlSecAssert2(dst->id == src->id, -1); /* allocate memory */ ret = xmlSecPtrListEnsureSize(dst, dst->use + src->use); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecPtrListGetName(src)), "xmlSecPtrListEnsureSize", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", src->use); return(-1); } /* copy one item after another */ for(i = 0; i < src->use; ++i, ++dst->use) { xmlSecAssert2(src->data != NULL, -1); xmlSecAssert2(dst->data != NULL, -1); if((dst->id->duplicateItem != NULL) && (src->data[i] != NULL)) { dst->data[dst->use] = dst->id->duplicateItem(src->data[i]); if(dst->data[dst->use] == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecPtrListGetName(src)), "duplicateItem", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } } else { dst->data[dst->use] = src->data[i]; } } return(0); }
static int xmlSecMSCryptoKWDes3SetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecMSCryptoKWDes3CtxPtr ctx; xmlSecBufferPtr buffer; xmlSecSize keySize; int ret; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecMSCryptoTransformKWDes3Id), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecMSCryptoKWDes3Size), -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecMSCryptoKeyDataDesId), -1); ctx = xmlSecMSCryptoKWDes3GetCtx(transform); xmlSecAssert2(ctx != NULL, -1); buffer = xmlSecKeyDataBinaryValueGetBuffer(xmlSecKeyGetValue(key)); xmlSecAssert2(buffer != NULL, -1); keySize = xmlSecBufferGetSize(buffer); if(keySize < XMLSEC_KW_DES3_KEY_LENGTH) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, "key length %d is not enough (%d expected)", keySize, XMLSEC_KW_DES3_KEY_LENGTH); return(-1); } ret = xmlSecBufferSetData(&(ctx->keyBuffer), xmlSecBufferGetData(buffer), XMLSEC_KW_DES3_KEY_LENGTH); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferSetData", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", XMLSEC_KW_DES3_KEY_LENGTH); return(-1); } return(0); }
/** * xmlSecCryptoDLGetLibraryFunctions: * @crypto: the desired crypto library name ("openssl", "nss", ...). * * Loads the xmlsec-<crypto> library and gets global crypto functions/transforms/keys data/keys store * table. This function is NOT thread safe, application MUST NOT call #xmlSecCryptoDLLoadLibrary, * #xmlSecCryptoDLGetLibraryFunctions, and #xmlSecCryptoDLUnloadLibrary functions from multiple threads. * * Returns the table or NULL if an error occurs. */ xmlSecCryptoDLFunctionsPtr xmlSecCryptoDLGetLibraryFunctions(const xmlChar* crypto) { xmlSecCryptoDLLibraryPtr lib; int pos; int ret; xmlSecAssert2(crypto != NULL, NULL); pos = xmlSecCryptoDLLibrariesListFindByName(&gXmlSecCryptoDLLibraries, crypto); if(pos >= 0) { lib = (xmlSecCryptoDLLibraryPtr)xmlSecPtrListGetItem(&gXmlSecCryptoDLLibraries, pos); xmlSecAssert2(lib != NULL, NULL); xmlSecAssert2(lib->functions != NULL, NULL); return(lib->functions); } lib = xmlSecCryptoDLLibraryCreate(crypto); if(lib == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecCryptoDLLibraryCreate", XMLSEC_ERRORS_R_XMLSEC_FAILED, "crypto=%s", xmlSecErrorsSafeString(crypto)); return(NULL); } ret = xmlSecPtrListAdd(&gXmlSecCryptoDLLibraries, lib); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecPtrListAdd", XMLSEC_ERRORS_R_XMLSEC_FAILED, "crypto=%s", xmlSecErrorsSafeString(crypto)); xmlSecCryptoDLLibraryDestroy(lib); return(NULL); } return(lib->functions); }
/** * xmlSecOpenSSLX509StoreAdoptCert: * @store: the pointer to X509 key data store klass. * @cert: the pointer to OpenSSL X509 certificate. * @type: the certificate type (trusted/untrusted). * * Adds trusted (root) or untrusted certificate to the store. * * Returns: 0 on success or a negative value if an error occurs. */ int xmlSecOpenSSLX509StoreAdoptCert(xmlSecKeyDataStorePtr store, X509* cert, xmlSecKeyDataType type) { xmlSecOpenSSLX509StoreCtxPtr ctx; int ret; xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecOpenSSLX509StoreId), -1); xmlSecAssert2(cert != NULL, -1); ctx = xmlSecOpenSSLX509StoreGetCtx(store); xmlSecAssert2(ctx != NULL, -1); if((type & xmlSecKeyDataTypeTrusted) != 0) { xmlSecAssert2(ctx->xst != NULL, -1); ret = X509_STORE_add_cert(ctx->xst, cert); if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_STORE_add_cert", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } /* add cert increments the reference */ X509_free(cert); } else { xmlSecAssert2(ctx->untrusted != NULL, -1); ret = sk_X509_push(ctx->untrusted, cert); if(ret < 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "sk_X509_push", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } } return(0); }
/** * xmlSecSoap12AddFaultReasonText: * @faultNode: the pointer to <Fault> node. * @faultReasonText: the new reason text. * @faultReasonLang: the new reason xml:lang attribute. * * Adds a new Text node to the Fault/Reason node. * * Returns a pointer to the newly created <Text> node or NULL if an error * occurs. */ EXPORT_C xmlNodePtr xmlSecSoap12AddFaultReasonText(xmlNodePtr faultNode, const xmlChar* faultReasonText, const xmlChar* faultReasonLang) { xmlNodePtr reasonNode; xmlNodePtr textNode; xmlSecAssert2(faultNode != NULL, NULL); xmlSecAssert2(faultReasonText != NULL, NULL); xmlSecAssert2(faultReasonLang != NULL, NULL); /* find Reason node */ reasonNode = xmlSecFindChild(faultNode, xmlSecNodeReason, xmlSecSoap12Ns); if(reasonNode == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecFindChild", XMLSEC_ERRORS_R_XMLSEC_FAILED, "node=%s", xmlSecErrorsSafeString(xmlSecNodeReason)); return(NULL); } /* add Text node */ textNode = xmlSecAddChild(reasonNode, xmlSecNodeText, xmlSecSoap12Ns); if(textNode == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecAddChild", XMLSEC_ERRORS_R_XMLSEC_FAILED, "node=%s", xmlSecErrorsSafeString(xmlSecNodeText)); return(NULL); } xmlNodeSetContent(textNode, faultReasonText); xmlNodeSetLang(textNode, faultReasonLang); return(textNode); }
static int xmlSecOpenSSLRsaOaepSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecOpenSSLRsaOaepCtxPtr ctx; EVP_PKEY* pKey; xmlSecAssert2(xmlSecTransformCheckId(transform, xmlSecOpenSSLTransformRsaOaepId), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationEncrypt) || (transform->operation == xmlSecTransformOperationDecrypt), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLRsaOaepSize), -1); xmlSecAssert2(key != NULL, -1); xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecOpenSSLKeyDataRsaId), -1); ctx = xmlSecOpenSSLRsaOaepGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->pKey == NULL, -1); pKey = xmlSecOpenSSLKeyDataRsaGetEvp(xmlSecKeyGetValue(key)); if(pKey == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecOpenSSLKeyDataRsaGetEvp", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } xmlSecAssert2(pKey->type == EVP_PKEY_RSA, -1); xmlSecAssert2(pKey->pkey.rsa != NULL, -1); ctx->pKey = xmlSecOpenSSLEvpKeyDup(pKey); if(ctx->pKey == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecOpenSSLEvpKeyDup", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(0); }
/** * xmlSecKeyDataCreate: * @id: the data id. * * Allocates and initializes new key data of the specified type @id. * Caller is responsible for destroying returned object with * #xmlSecKeyDataDestroy function. * * Returns: the pointer to newly allocated key data structure * or NULL if an error occurs. */ xmlSecKeyDataPtr xmlSecKeyDataCreate(xmlSecKeyDataId id) { xmlSecKeyDataPtr data; int ret; xmlSecAssert2(id != NULL, NULL); xmlSecAssert2(id->klassSize >= sizeof(xmlSecKeyDataKlass), NULL); xmlSecAssert2(id->objSize >= sizeof(xmlSecKeyData), NULL); xmlSecAssert2(id->name != NULL, NULL); /* Allocate a new xmlSecKeyData and fill the fields. */ data = (xmlSecKeyDataPtr)xmlMalloc(id->objSize); if(data == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, "size=%d", id->objSize); return(NULL); } memset(data, 0, id->objSize); data->id = id; if(id->initialize != NULL) { ret = (id->initialize)(data); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id)), "id->initialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyDataDestroy(data); return(NULL); } } return(data); }
static int xmlSecNssKWAesInitialize(xmlSecTransformPtr transform) { xmlSecNssKWAesCtxPtr ctx; int ret; xmlSecAssert2(xmlSecNssKWAesCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKWAesSize), -1); ctx = xmlSecNssKWAesGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); if(xmlSecTransformCheckId(transform, xmlSecNssTransformKWAes128Id)) { ctx->keyExpectedSize = XMLSEC_KW_AES128_KEY_SIZE; } else if(xmlSecTransformCheckId(transform, xmlSecNssTransformKWAes192Id)) { ctx->keyExpectedSize = XMLSEC_KW_AES192_KEY_SIZE; } else if(xmlSecTransformCheckId(transform, xmlSecNssTransformKWAes256Id)) { ctx->keyExpectedSize = XMLSEC_KW_AES256_KEY_SIZE; } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_TRANSFORM, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ret = xmlSecBufferInitialize(&(ctx->keyBuffer), 0); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferInitialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(0); }
/** * xmlSecKeyEnsureData: * @key: the pointer to key. * @dataId: the requested data klass. * * If necessary, creates key data of @dataId klass and adds to @key. * * Returns: pointer to key data or NULL if an error occurs. */ xmlSecKeyDataPtr xmlSecKeyEnsureData(xmlSecKeyPtr key, xmlSecKeyDataId dataId) { xmlSecKeyDataPtr data; int ret; xmlSecAssert2(key != NULL, NULL); xmlSecAssert2(dataId != xmlSecKeyDataIdUnknown, NULL); data = xmlSecKeyGetData(key, dataId); if(data != NULL) { return(data); } data = xmlSecKeyDataCreate(dataId); if(data == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyDataCreate", XMLSEC_ERRORS_R_XMLSEC_FAILED, "dataId=%s", xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId))); return(NULL); } ret = xmlSecKeyAdoptData(key, data); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecKeyAdoptData", XMLSEC_ERRORS_R_XMLSEC_FAILED, "dataId=%s", xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(dataId))); xmlSecKeyDataDestroy(data); return(NULL); } return(data); }
static int xmlSecOpenSSLEvpSignatureVerify(xmlSecTransformPtr transform, const xmlSecByte* data, xmlSecSize dataSize, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLEvpSignatureCtxPtr ctx; int ret; xmlSecAssert2(xmlSecOpenSSLEvpSignatureCheckId(transform), -1); xmlSecAssert2(transform->operation == xmlSecTransformOperationVerify, -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLEvpSignatureSize), -1); xmlSecAssert2(transform->status == xmlSecTransformStatusFinished, -1); xmlSecAssert2(data != NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLEvpSignatureGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); ret = EVP_VerifyFinal(&(ctx->digestCtx), (xmlSecByte*)data, dataSize, ctx->pKey); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_VerifyFinal", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } else if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "EVP_VerifyFinal", XMLSEC_ERRORS_R_DATA_NOT_MATCH, "signature do not match"); transform->status = xmlSecTransformStatusFail; return(0); } transform->status = xmlSecTransformStatusOk; return(0); }
/** * xmlSecOpenSSLAppKeyLoad: * @filename: the key filename. * @format: the key file format. * @pwd: the key file password. * @pwdCallback: the key password callback. * @pwdCallbackCtx: the user context for password callback. * * Reads key from the a file. * * Returns: pointer to the key or NULL if an error occurs. */ xmlSecKeyPtr xmlSecOpenSSLAppKeyLoad(const char *filename, xmlSecKeyDataFormat format, const char *pwd, void* pwdCallback, void* pwdCallbackCtx) { BIO* bio; xmlSecKeyPtr key; xmlSecAssert2(filename != NULL, NULL); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL); bio = BIO_new_file(filename, "rb"); if(bio == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "BIO_new_file", XMLSEC_ERRORS_R_CRYPTO_FAILED, "filename=%s;errno=%d", xmlSecErrorsSafeString(filename), errno); return(NULL); } key = xmlSecOpenSSLAppKeyLoadBIO (bio, format, pwd, pwdCallback, pwdCallbackCtx); if(key == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecOpenSSLAppKeyLoadBIO", XMLSEC_ERRORS_R_XMLSEC_FAILED, "filename=%s;errno=%d", xmlSecErrorsSafeString(filename), errno); BIO_free(bio); return(NULL); } BIO_free(bio); return(key); }
/** * xmlSecOpenSSLAppKeyCertLoad: * @key: the pointer to key. * @filename: the certificate filename. * @format: the certificate file format. * * Reads the certificate from $@filename and adds it to key. * * Returns: 0 on success or a negative value otherwise. */ int xmlSecOpenSSLAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, xmlSecKeyDataFormat format) { BIO* bio; int ret; xmlSecAssert2(key != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); bio = BIO_new_file(filename, "rb"); if(bio == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "BIO_new_file", XMLSEC_ERRORS_R_CRYPTO_FAILED, "filename=%s;errno=%d", xmlSecErrorsSafeString(filename), errno); return(-1); } ret = xmlSecOpenSSLAppKeyCertLoadBIO (key, bio, format); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecOpenSSLAppKeyCertLoadBIO", XMLSEC_ERRORS_R_XMLSEC_FAILED, "filename=%s;errno=%d", xmlSecErrorsSafeString(filename), errno); BIO_free(bio); return(-1); } BIO_free(bio); return(0); }
/** * xmlSecKeyStoreCreate: * @id: the key store klass. * * Creates new store of the specified klass @klass. Caller is responsible * for freeing the returned store by calling #xmlSecKeyStoreDestroy function. * * Returns the pointer to newly allocated keys store or NULL if an error occurs. */ xmlSecKeyStorePtr xmlSecKeyStoreCreate(xmlSecKeyStoreId id) { xmlSecKeyStorePtr store; int ret; xmlSecAssert2(id != NULL, NULL); xmlSecAssert2(id->objSize > 0, NULL); /* Allocate a new xmlSecKeyStore and fill the fields. */ store = (xmlSecKeyStorePtr)xmlMalloc(id->objSize); if(store == NULL) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreKlassGetName(id)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, "size=%d", id->objSize); return(NULL); } memset(store, 0, id->objSize); store->id = id; if(id->initialize != NULL) { ret = (id->initialize)(store); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreKlassGetName(id)), "id->initialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecKeyStoreDestroy(store); return(NULL); } } return(store); }
static int xmlSecOpenSSLHmacNodeRead(xmlSecTransformPtr transform, xmlNodePtr node, xmlSecTransformCtxPtr transformCtx) { xmlSecOpenSSLHmacCtxPtr ctx; xmlNodePtr cur; xmlSecAssert2(xmlSecOpenSSLHmacCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecOpenSSLHmacSize), -1); xmlSecAssert2(node!= NULL, -1); xmlSecAssert2(transformCtx != NULL, -1); ctx = xmlSecOpenSSLHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); cur = xmlSecGetNextElementNode(node->children); if((cur != NULL) && xmlSecCheckNodeName(cur, xmlSecNodeHMACOutputLength, xmlSecDSigNs)) { xmlChar *content; content = xmlNodeGetContent(cur); if(content != NULL) { ctx->dgstSize = atoi((char*)content); xmlFree(content); } /* todo: error if dgstSize == 0 ?*/ cur = xmlSecGetNextElementNode(cur->next); } if(cur != NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), xmlSecErrorsSafeString(xmlSecNodeGetName(cur)), XMLSEC_ERRORS_R_UNEXPECTED_NODE, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(0); }
int xmlSecMSCryptoAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, xmlSecKeyDataFormat format) { xmlSecBuffer buffer; int ret; xmlSecAssert2(key != NULL, -1); xmlSecAssert2(filename != NULL, -1); xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1); ret = xmlSecBufferInitialize(&buffer, 0); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecBufferInitialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ret = xmlSecBufferReadFile(&buffer, filename); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecBufferReadFile", XMLSEC_ERRORS_R_XMLSEC_FAILED, "filename=%s", xmlSecErrorsSafeString(filename)); xmlSecBufferFinalize(&buffer); return (-1); } ret = xmlSecMSCryptoAppKeyCertLoadMemory(key, xmlSecBufferGetData(&buffer), xmlSecBufferGetSize(&buffer), format); if (ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "xmlSecMSCryptoAppKeyCertLoadMemory", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlSecBufferFinalize(&buffer); return(-1); } xmlSecBufferFinalize(&buffer); return(0); }
/** * xmlSecNssAppInit: * @config: the path to NSS database files. * * General crypto engine initialization. This function is used * by XMLSec command line utility and called before * @xmlSecInit function. * * Returns: 0 on success or a negative value otherwise. */ int xmlSecNssAppInit(const char* config) { SECStatus rv; if(config) { rv = NSS_InitReadWrite(config); if(rv != SECSuccess) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "NSS_InitReadWrite", XMLSEC_ERRORS_R_CRYPTO_FAILED, "config=%s", xmlSecErrorsSafeString(config)); return(-1); } } else { rv = NSS_NoDB_Init(NULL); if(rv != SECSuccess) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "NSS_NoDB_Init", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } } /* configure PKCS11 */ PK11_ConfigurePKCS11("manufacturesID", "libraryDescription", "tokenDescription", "privateTokenDescription", "slotDescription", "privateSlotDescription", "fipsSlotDescription", "fipsPrivateSlotDescription", 0, 0); /* setup for PKCS12 */ PORT_SetUCS2_ASCIIConversionFunction(xmlSecNssAppAscii2UCS2Conv); SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1); SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1); SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1); SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1); SEC_PKCS12EnableCipher(PKCS12_DES_56, 1); SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1); SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1); return(0); }
/** * xmlSecKeyGenerateByName: * @name: the requested key klass name (rsa, dsa, aes, ...). * @sizeBits: the new key size (in bits!). * @type: the new key type (session, permanent, ...). * * Generates new key of requested @klass and @type. * * Returns: pointer to newly created key or NULL if an error occurs. */ xmlSecKeyPtr xmlSecKeyGenerateByName(const xmlChar* name, xmlSecSize sizeBits, xmlSecKeyDataType type) { xmlSecKeyDataId dataId; xmlSecAssert2(name != NULL, NULL); dataId = xmlSecKeyDataIdListFindByName(xmlSecKeyDataIdsGet(), name, xmlSecKeyDataUsageAny); if(dataId == xmlSecKeyDataIdUnknown) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, xmlSecErrorsSafeString(name), XMLSEC_ERRORS_R_KEY_DATA_NOT_FOUND, XMLSEC_ERRORS_NO_MESSAGE); return(NULL); } return(xmlSecKeyGenerate(dataId, sizeBits, type)); }
static int xmlSecPtrListEnsureSize(xmlSecPtrListPtr list, xmlSecSize size) { xmlSecPtr* newData; xmlSecSize newSize = 0; xmlSecAssert2(xmlSecPtrListIsValid(list), -1); if(size < list->max) { return(0); } switch(list->allocMode) { case xmlSecAllocModeExact: newSize = size + 8; break; case xmlSecAllocModeDouble: newSize = 2 * size + 32; break; } if(newSize < gInitialSize) { newSize = gInitialSize; } if(list->data != NULL) { newData = (xmlSecPtr*)xmlRealloc(list->data, sizeof(xmlSecPtr) * newSize); } else { newData = (xmlSecPtr*)xmlMalloc(sizeof(xmlSecPtr) * newSize); } if(newData == NULL) { xmlSecErr_a_ignorar7(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecPtrListGetName(list)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, "sizeof(xmlSecPtr)*%d=%d", newSize, sizeof(xmlSecPtr) * newSize); return(-1); } list->data = newData; list->max = newSize; return(0); }
/** * xmlSecKeyDataIdsRegister: * @id: the key data klass. * * Registers @id in the global list of key data klasses. * * Returns: 0 on success or a negative value if an error occurs. */ int xmlSecKeyDataIdsRegister(xmlSecKeyDataId id) { int ret; xmlSecAssert2(id != xmlSecKeyDataIdUnknown, -1); ret = xmlSecPtrListAdd(xmlSecKeyDataIdsGet(), (xmlSecPtr)id); if(ret < 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlSecPtrListAdd", XMLSEC_ERRORS_R_XMLSEC_FAILED, "dataId=%s", xmlSecErrorsSafeString(xmlSecKeyDataKlassGetName(id))); return(-1); } return(0); }
static int xmlSecNssKWAesInitialize(xmlSecTransformPtr transform) { int ret; xmlSecAssert2(xmlSecNssKWAesCheckId(transform), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecNssKWAesSize), -1); ret = xmlSecBufferInitialize(xmlSecNssKWAesGetKey(transform), 0); if(ret < 0) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "xmlSecBufferInitialize", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } return(0); }
/** * xmlSecPtrListAdd: * @list: the pointer to list. * @item: the item. * * Adds @item to the end of the @list. * * Returns 0 on success or a negative value if an error occurs. */ int xmlSecPtrListAdd(xmlSecPtrListPtr list, xmlSecPtr item) { int ret; xmlSecAssert2(xmlSecPtrListIsValid(list), -1); ret = xmlSecPtrListEnsureSize(list, list->use + 1); if(ret < 0) { xmlSecErr_a_ignorar6(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecPtrListGetName(list)), "xmlSecPtrListAdd", XMLSEC_ERRORS_R_XMLSEC_FAILED, "size=%d", list->use + 1); return(-1); } list->data[list->use++] = item; return(0); }