Esempio n. 1
0
/**
  Create DSA parameters
  @param prng          An active PRNG state
  @param wprng         The index of the PRNG desired
  @param group_size    Size of the multiplicative group (octets)
  @param modulus_size  Size of the modulus (octets)
  @param p             [out] bignum where generated 'p' is stored (must be initialized by caller)
  @param q             [out] bignum where generated 'q' is stored (must be initialized by caller)
  @param g             [out] bignum where generated 'g' is stored (must be initialized by caller)
  @return CRYPT_OK if successful, upon error this function will free all allocated memory
*/
static int dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g)
{
  unsigned long L, N, n, outbytes, seedbytes, counter, j, i;
  int err, res, mr_tests_q, mr_tests_p, found_p, found_q, hash;
  unsigned char *wbuf, *sbuf, digest[MAXBLOCKSIZE];
  void *t2L1, *t2N1, *t2q, *t2seedlen, *U, *W, *X, *c, *h, *e, *seedinc;

  /* check size */
  if (group_size >= LTC_MDSA_MAX_GROUP || group_size < 1 || group_size >= modulus_size) {
    return CRYPT_INVALID_ARG;
  }

 /* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
  *
  * L = The desired length of the prime p (in bits e.g. L = 1024)
  * N = The desired length of the prime q (in bits e.g. N = 160)
  * seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N
  * outlen  = The bit length of Hash function
  *
  * 1.  Check that the (L, N)
  * 2.  If (seedlen <N), then return INVALID.
  * 3.  n = ceil(L / outlen) - 1
  * 4.  b = L- 1 - (n * outlen)
  * 5.  domain_parameter_seed = an arbitrary sequence of seedlen bits
  * 6.  U = Hash (domain_parameter_seed) mod 2^(N-1)
  * 7.  q = 2^(N-1) + U + 1 - (U mod 2)
  * 8.  Test whether or not q is prime as specified in Appendix C.3
  * 9.  If qis not a prime, then go to step 5.
  * 10. offset = 1
  * 11. For counter = 0 to (4L- 1) do {
  *       For j=0 to n do {
  *         Vj = Hash ((domain_parameter_seed+ offset + j) mod 2^seedlen
  *       }
  *       W = V0 + (V1 *2^outlen) + ... + (Vn-1 * 2^((n-1) * outlen)) + ((Vn mod 2^b) * 2^(n * outlen))
  *       X = W + 2^(L-1)           Comment: 0 <= W < 2^(L-1); hence 2^(L-1) <= X < 2^L
  *       c = X mod 2*q
  *       p = X - (c - 1)           Comment: p ~ 1 (mod 2*q)
  *       If (p >= 2^(L-1)) {
  *         Test whether or not p is prime as specified in Appendix C.3.
  *         If p is determined to be prime, then return VALID and the values of p, qand (optionally) the values of domain_parameter_seed and counter
  *       }
  *       offset = offset + n + 1   Comment: Increment offset
  *     }
  */

  seedbytes = group_size;
  L = modulus_size * 8;
  N = group_size * 8;

  /* M-R tests (when followed by one Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
  mr_tests_p = (L <= 2048) ? 3 : 2;
  if      (N <= 160)  { mr_tests_q = 19; }
  else if (N <= 224)  { mr_tests_q = 24; }
  else                { mr_tests_q = 27; }

  if (N <= 256) {
    hash = register_hash(&sha256_desc);
  }
  else if (N <= 384) {
    hash = register_hash(&sha384_desc);
  }
  else if (N <= 512) {
    hash = register_hash(&sha512_desc);
  }
  else {
    return CRYPT_INVALID_ARG; /* group_size too big */
  }

  if ((err = hash_is_valid(hash)) != CRYPT_OK)                                   { return err; }
  outbytes = hash_descriptor[hash]->hashsize;

  n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1;

  if ((wbuf = XMALLOC((n+1)*outbytes)) == NULL)                                  { err = CRYPT_MEM; goto cleanup3; }
  if ((sbuf = XMALLOC(seedbytes)) == NULL)                                       { err = CRYPT_MEM; goto cleanup2; }

  err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, NULL);
  if (err != CRYPT_OK)                                                           { goto cleanup1; }

  if ((err = mp_2expt(t2L1, L-1)) != CRYPT_OK)                                   { goto cleanup; }
  /* t2L1 = 2^(L-1) */
  if ((err = mp_2expt(t2N1, N-1)) != CRYPT_OK)                                   { goto cleanup; }
  /* t2N1 = 2^(N-1) */
  if ((err = mp_2expt(t2seedlen, seedbytes*8)) != CRYPT_OK)                      { goto cleanup; }
  /* t2seedlen = 2^seedlen */

  for(found_p=0; !found_p;) {
    /* q */
    for(found_q=0; !found_q;) {
      if (prng_descriptor[wprng]->read(sbuf, seedbytes, prng) != seedbytes)       { err = CRYPT_ERROR_READPRNG; goto cleanup; }
      i = outbytes;
      if ((err = hash_memory(hash, sbuf, seedbytes, digest, &i)) != CRYPT_OK)    { goto cleanup; }
      if ((err = mp_read_unsigned_bin(U, digest, outbytes)) != CRYPT_OK)         { goto cleanup; }
      if ((err = mp_mod(U, t2N1, U)) != CRYPT_OK)                                { goto cleanup; }
      if ((err = mp_add(t2N1, U, q)) != CRYPT_OK)                                { goto cleanup; }
      if (!mp_isodd(q)) mp_add_d(q, 1, q);
      if ((err = mp_prime_is_prime(q, mr_tests_q, &res)) != CRYPT_OK)            { goto cleanup; }       /* XXX-TODO rounds are ignored; no Lucas test */
      if (res == LTC_MP_YES) found_q = 1;
    }

    /* p */
    if ((err = mp_read_unsigned_bin(seedinc, sbuf, seedbytes)) != CRYPT_OK)      { goto cleanup; }
    if ((err = mp_add(q, q, t2q)) != CRYPT_OK)                                   { goto cleanup; }
    for(counter=0; counter < 4*L && !found_p; counter++) {
      for(j=0; j<=n; j++) {
        if ((err = mp_add_d(seedinc, 1, seedinc)) != CRYPT_OK)                   { goto cleanup; }
        if ((err = mp_mod(seedinc, t2seedlen, seedinc)) != CRYPT_OK)             { goto cleanup; }
        /* seedinc = (seedinc+1) % 2^seed_bitlen */
        if ((i = mp_unsigned_bin_size(seedinc)) > seedbytes)                     { err = CRYPT_INVALID_ARG; goto cleanup; }
        zeromem(sbuf, seedbytes);
        if ((err = mp_to_unsigned_bin(seedinc, sbuf + seedbytes-i)) != CRYPT_OK) { goto cleanup; }
        i = outbytes;
        err = hash_memory(hash, sbuf, seedbytes, wbuf+(n-j)*outbytes, &i);
        if (err != CRYPT_OK)                                                     { goto cleanup; }
      }
      if ((err = mp_read_unsigned_bin(W, wbuf, (n+1)*outbytes)) != CRYPT_OK)     { goto cleanup; }
      if ((err = mp_mod(W, t2L1, W)) != CRYPT_OK)                                { goto cleanup; }
      if ((err = mp_add(W, t2L1, X)) != CRYPT_OK)                                { goto cleanup; }
      if ((err = mp_mod(X, t2q, c))  != CRYPT_OK)                                { goto cleanup; }
      if ((err = mp_sub_d(c, 1, p))  != CRYPT_OK)                                { goto cleanup; }
      if ((err = mp_sub(X, p, p))    != CRYPT_OK)                                { goto cleanup; }
      if (mp_cmp(p, t2L1) != LTC_MP_LT) {
        /* p >= 2^(L-1) */
        if ((err = mp_prime_is_prime(p, mr_tests_p, &res)) != CRYPT_OK)          { goto cleanup; }       /* XXX-TODO rounds are ignored; no Lucas test */
        if (res == LTC_MP_YES) {
          found_p = 1;
        }
      }
    }
  }

 /* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g
  * 1. e = (p - 1)/q
  * 2. h = any integer satisfying: 1 < h < (p - 1)
  *    h could be obtained from a random number generator or from a counter that changes after each use
  * 3. g = h^e mod p
  * 4. if (g == 1), then go to step 2.
  *
  */

  if ((err = mp_sub_d(p, 1, e)) != CRYPT_OK)                                     { goto cleanup; }
  if ((err = mp_div(e, q, e, c)) != CRYPT_OK)                                    { goto cleanup; }
  /* e = (p - 1)/q */
  i = mp_count_bits(p);
  do {
    do {
      if ((err = rand_bn_bits(h, i, prng, wprng)) != CRYPT_OK)                   { goto cleanup; }
    } while (mp_cmp(h, p) != LTC_MP_LT || mp_cmp_d(h, 2) != LTC_MP_GT);
    if ((err = mp_sub_d(h, 1, h)) != CRYPT_OK)                                   { goto cleanup; }
    /* h is randon and 1 < h < (p-1) */
    if ((err = mp_exptmod(h, e, p, g)) != CRYPT_OK)                              { goto cleanup; }
  } while (mp_cmp_d(g, 1) == LTC_MP_EQ);

  err = CRYPT_OK;
cleanup:
  mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, NULL);
cleanup1:
  XFREE(sbuf);
cleanup2:
  XFREE(wbuf);
cleanup3:
  return err;
}
Esempio n. 2
0
/* alloc user allocs to work with zlib */
static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
{
    (void)opaque;
    return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
}
Esempio n. 3
0
/**
  PKCS #1 pad then sign
  @param in        The hash to sign
  @param inlen     The length of the hash to sign (octets)
  @param out       [out] The signature
  @param outlen    [in/out] The max size and resulting size of the signature
  @param padding   Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5)
  @param prng      An active PRNG state
  @param prng_idx  The index of the PRNG desired
  @param hash_idx  The index of the hash desired
  @param saltlen   The length of the salt desired (octets)
  @param key       The private RSA key to use
  @return CRYPT_OK if successful
*/
int rsa_sign_hash_ex(const unsigned char *in,       unsigned long  inlen,
                           unsigned char *out,      unsigned long *outlen,
                           int            padding,
                           prng_state    *prng,     int            prng_idx,
                           int            hash_idx, unsigned long  saltlen,
                           rsa_key *key)
{
   unsigned long modulus_bitlen, modulus_bytelen, x, y;
   int           err;

   LTC_ARGCHK(in       != NULL);
   LTC_ARGCHK(out      != NULL);
   LTC_ARGCHK(outlen   != NULL);
   LTC_ARGCHK(key      != NULL);

   /* valid padding? */
   if ((padding != LTC_PKCS_1_V1_5) && (padding != LTC_PKCS_1_PSS)) {
     return CRYPT_PK_INVALID_PADDING;
   }

   if (padding == LTC_PKCS_1_PSS) {
     /* valid prng and hash ? */
     if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
        return err;
     }
     if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
        return err;
     }
   }

   /* get modulus len in bits */
   modulus_bitlen = mp_count_bits((key->N));

  /* outlen must be at least the size of the modulus */
  modulus_bytelen = mp_unsigned_bin_size((key->N));
  if (modulus_bytelen > *outlen) {
     *outlen = modulus_bytelen;
     return CRYPT_BUFFER_OVERFLOW;
  }

  if (padding == LTC_PKCS_1_PSS) {
    /* PSS pad the key */
    x = *outlen;
    if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx,
                                 hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) {
       return err;
    }
  } else {
    /* PKCS #1 v1.5 pad the hash */
    unsigned char *tmpin;
    ltc_asn1_list digestinfo[2], siginfo[2];

    /* not all hashes have OIDs... so sad */
    if (hash_descriptor[hash_idx]->OIDlen == 0) {
       return CRYPT_INVALID_ARG;
    }

    /* construct the SEQUENCE 
      SEQUENCE {
         SEQUENCE {hashoid OID
                   blah    NULL
         }
         hash    OCTET STRING 
      }
   */
    LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx]->OID, hash_descriptor[hash_idx]->OIDlen);
    LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL,              NULL,                          0);
    LTC_SET_ASN1(siginfo,    0, LTC_ASN1_SEQUENCE,          digestinfo,                    2);
    LTC_SET_ASN1(siginfo,    1, LTC_ASN1_OCTET_STRING,      in,                            inlen);

    /* allocate memory for the encoding */
    y = mp_unsigned_bin_size(key->N);
    tmpin = XMALLOC(y);
    if (tmpin == NULL) {
       return CRYPT_MEM;
    }

    if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) {
       XFREE(tmpin);
       return err;
    }

    x = *outlen;
    if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA,
                                  modulus_bitlen, NULL, 0,
                                  out, &x)) != CRYPT_OK) {
      XFREE(tmpin);
      return err;
    }
    XFREE(tmpin);
  }

  /* RSA encode it */
  return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key);
}
Esempio n. 4
0
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
{
    byte* ocspReqBuf = NULL;
    int ocspReqSz = 2048;
    byte* ocspRespBuf = NULL;
    int result = -1;
    OCSP_Entry* ocspe;
    CertStatus* certStatus = NULL;
    const char *url;
    int urlSz;
#ifdef WOLFSSL_SMALL_STACK
    CertStatus* newStatus;
    OcspRequest* ocspRequest;
    OcspResponse* ocspResponse;
#else
    CertStatus newStatus[1];
    OcspRequest ocspRequest[1];
    OcspResponse ocspResponse[1];
#endif

    WOLFSSL_ENTER("CheckCertOCSP");

    if (LockMutex(&ocsp->ocspLock) != 0) {
        WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
        return BAD_MUTEX_E;
    }

    ocspe = ocsp->ocspList;
    while (ocspe) {
        if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
            && XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash,
                                                        SHA_DIGEST_SIZE) == 0)
            break;
        else
            ocspe = ocspe->next;
    }

    if (ocspe == NULL) {
        ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
                                                NULL, DYNAMIC_TYPE_OCSP_ENTRY);
        if (ocspe != NULL) {
            InitOCSP_Entry(ocspe, cert);
            ocspe->next = ocsp->ocspList;
            ocsp->ocspList = ocspe;
        }
        else {
            UnLockMutex(&ocsp->ocspLock);
            WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
            return MEMORY_ERROR;
        }
    }
    else {
        certStatus = ocspe->status;
        while (certStatus) {
            if (certStatus->serialSz == cert->serialSz &&
                 XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0)
                break;
            else
                certStatus = certStatus->next;
        }
    }

    if (certStatus != NULL) {
        if (!ValidateDate(certStatus->thisDate,
                                        certStatus->thisDateFormat, BEFORE) ||
            (certStatus->nextDate[0] == 0) ||
            !ValidateDate(certStatus->nextDate,
                                        certStatus->nextDateFormat, AFTER)) {
            WOLFSSL_MSG("\tinvalid status date, looking up cert");
        }
        else {
            result = xstat2err(certStatus->status);
            UnLockMutex(&ocsp->ocspLock);
            WOLFSSL_LEAVE("CheckCertOCSP", result);
            return result;
        }
    }

    UnLockMutex(&ocsp->ocspLock);

    if (ocsp->cm->ocspUseOverrideURL) {
        url = ocsp->cm->ocspOverrideURL;
        if (url != NULL && url[0] != '\0')
            urlSz = (int)XSTRLEN(url);
        else
            return OCSP_NEED_URL;
    }
    else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
        url = (const char *)cert->extAuthInfo;
        urlSz = cert->extAuthInfoSz;
    }
    else {
        /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
        return 0;
    }

    ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
    if (ocspReqBuf == NULL) {
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
        return MEMORY_ERROR;
    }

#ifdef WOLFSSL_SMALL_STACK
    newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
                                                       DYNAMIC_TYPE_TMP_BUFFER);
    ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
                                                       DYNAMIC_TYPE_TMP_BUFFER);
    ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
                                                       DYNAMIC_TYPE_TMP_BUFFER);

    if (newStatus == NULL || ocspRequest == NULL || ocspResponse == NULL) {
        if (newStatus)    XFREE(newStatus,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (ocspRequest)  XFREE(ocspRequest,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);

        XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);

        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
        return MEMORY_E;
    }
#endif

    InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
                                                         ocspReqBuf, ocspReqSz);
    ocspReqSz = EncodeOcspRequest(ocspRequest);
    
    if (ocsp->cm->ocspIOCb)
        result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
                                           ocspReqBuf, ocspReqSz, &ocspRespBuf);

    if (result >= 0 && ocspRespBuf) {
        XMEMSET(newStatus, 0, sizeof(CertStatus));

        InitOcspResponse(ocspResponse, newStatus, ocspRespBuf, result);
        OcspResponseDecode(ocspResponse);
    
        if (ocspResponse->responseStatus != OCSP_SUCCESSFUL)
            result = OCSP_LOOKUP_FAIL;
        else {
            if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
                result = xstat2err(ocspResponse->status->status);

                if (LockMutex(&ocsp->ocspLock) != 0)
                    result = BAD_MUTEX_E;
                else {
                    if (certStatus != NULL)
                        /* Replace existing certificate entry with updated */
                        XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
                    else {
                        /* Save new certificate entry */
                        certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus),
                                          NULL, DYNAMIC_TYPE_OCSP_STATUS);
                        if (certStatus != NULL) {
                            XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
                            certStatus->next = ocspe->status;
                            ocspe->status = certStatus;
                            ocspe->totalStatus++;
                        }
                    }

                    UnLockMutex(&ocsp->ocspLock);
                }
            }
            else
                result = OCSP_LOOKUP_FAIL;
        }
    }
    else
        result = OCSP_LOOKUP_FAIL;

    XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);

#ifdef WOLFSSL_SMALL_STACK
    XFREE(newStatus,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(ocspRequest,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb)
        ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf);

    WOLFSSL_LEAVE("CheckCertOCSP", result);
    return result;
}
Esempio n. 5
0
int EmbedOcspLookup(void* ctx, const char* url, int urlSz,
                        byte* ocspReqBuf, int ocspReqSz, byte** ocspRespBuf)
{
    SOCKET_T sfd = 0;
    word16   port;
    int      ret = -1;
#ifdef WOLFSSL_SMALL_STACK
    char*    path;
    char*    domainName;
#else
    char     path[80];
    char     domainName[80];
#endif

#ifdef WOLFSSL_SMALL_STACK
    path = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (path == NULL)
        return -1;
    
    domainName = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (domainName == NULL) {
        XFREE(path, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return -1;
    }
#endif

    (void)ctx;

    if (ocspReqBuf == NULL || ocspReqSz == 0) {
        WOLFSSL_MSG("OCSP request is required for lookup");
    }
    else if (ocspRespBuf == NULL) {
        WOLFSSL_MSG("Cannot save OCSP response");
    }
    else if (decode_url(url, urlSz, domainName, path, &port) < 0) {
        WOLFSSL_MSG("Unable to decode OCSP URL");
    }
    else {
        /* Note, the library uses the EmbedOcspRespFree() callback to
         * free this buffer. */
        int   httpBufSz = SCRATCH_BUFFER_SIZE;
        byte* httpBuf   = (byte*)XMALLOC(httpBufSz, NULL,
                                                        DYNAMIC_TYPE_OCSP);

        if (httpBuf == NULL) {
            WOLFSSL_MSG("Unable to create OCSP response buffer");
        }
        else {
            httpBufSz = build_http_request(domainName, path, ocspReqSz,
                                                            httpBuf, httpBufSz);

            if ((tcp_connect(&sfd, domainName, port) != 0) || (sfd <= 0)) {
                WOLFSSL_MSG("OCSP Responder connection failed");
            }
            else if ((int)SEND_FUNCTION(sfd, (char*)httpBuf, httpBufSz, 0) !=
                                                                    httpBufSz) {
                WOLFSSL_MSG("OCSP http request failed");
            }
            else if ((int)SEND_FUNCTION(sfd, (char*)ocspReqBuf, ocspReqSz, 0) !=
                                                                    ocspReqSz) {
                WOLFSSL_MSG("OCSP ocsp request failed");
            }
            else {
                ret = process_http_response(sfd, ocspRespBuf, httpBuf,
                                                           SCRATCH_BUFFER_SIZE);
            }

            CLOSE_FUNCTION(sfd);
            XFREE(httpBuf, NULL, DYNAMIC_TYPE_OCSP);
        }
    }

#ifdef WOLFSSL_SMALL_STACK
    XFREE(path,       NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(domainName, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    return ret;
}
/**
  Encrypt a symmetric key with ECC 
  @param in         The symmetric key you want to encrypt
  @param inlen      The length of the key to encrypt (octets)
  @param out        [out] The destination for the ciphertext
  @param outlen     [in/out] The max size and resulting size of the ciphertext
  @param prng       An active PRNG state
  @param wprng      The index of the PRNG you wish to use 
  @param hash       The index of the hash you want to use 
  @param key        The ECC key you want to encrypt to
  @return CRYPT_OK if successful
*/
int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen,
                          unsigned char *out,  unsigned long *outlen, 
                          prng_state *prng, int wprng, int hash, 
                          ecc_key *key)
{
    unsigned char *pub_expt, *ecc_shared, *skey;
    ecc_key        pubkey;
    unsigned long  x, y, pubkeysize;
    int            err;

    LTC_ARGCHK(in      != NULL);
    LTC_ARGCHK(out     != NULL);
    LTC_ARGCHK(outlen  != NULL);
    LTC_ARGCHK(key     != NULL);

    /* check that wprng/cipher/hash are not invalid */
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
       return err;
    }

    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
       return err;
    }

    if (inlen > hash_descriptor[hash].hashsize) {
       return CRYPT_INVALID_HASH;
    }

    /* make a random key and export the public copy */
    if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
       return err;
    }

    pub_expt   = XMALLOC(ECC_BUF_SIZE);
    ecc_shared = XMALLOC(ECC_BUF_SIZE);
    skey       = XMALLOC(MAXBLOCKSIZE);
    if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
       if (pub_expt != NULL) {
          XFREE(pub_expt);
       }
       if (ecc_shared != NULL) {
          XFREE(ecc_shared);
       }
       if (skey != NULL) {
          XFREE(skey);
       }
       ecc_free(&pubkey);
       return CRYPT_MEM;
    }

    pubkeysize = ECC_BUF_SIZE;
    if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
       ecc_free(&pubkey);
       goto LBL_ERR;
    }
    
    /* make random key */
    x        = ECC_BUF_SIZE;
    if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
       ecc_free(&pubkey);
       goto LBL_ERR;
    }
    ecc_free(&pubkey);
    y = MAXBLOCKSIZE;
    if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
       goto LBL_ERR;
    }
    
    /* Encrypt key */
    for (x = 0; x < inlen; x++) {
      skey[x] ^= in[x];
    }

    err = der_encode_sequence_multi(out, outlen,
                                    LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID,
                                    LTC_ASN1_OCTET_STRING,       pubkeysize,                     pub_expt,
                                    LTC_ASN1_OCTET_STRING,       inlen,                          skey,
                                    LTC_ASN1_EOL,                0UL,                            NULL);

LBL_ERR:
#ifdef LTC_CLEAN_STACK
    /* clean up */
    zeromem(pub_expt,   ECC_BUF_SIZE);
    zeromem(ecc_shared, ECC_BUF_SIZE);
    zeromem(skey,       MAXBLOCKSIZE);
#endif

    XFREE(skey);
    XFREE(ecc_shared);
    XFREE(pub_expt);

    return err;
}
/**
   Execute PKCS #5 v1
   @param password         The password (or key)
   @param password_len     The length of the password (octet)
   @param salt             The salt (or nonce) which is 8 octets long
   @param iteration_count  The PKCS #5 v1 iteration count
   @param hash_idx         The index of the hash desired
   @param out              [out] The destination for this algorithm
   @param outlen           [in/out] The max size and resulting size of the algorithm output
   @return CRYPT_OK if successful
*/
int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, 
                const unsigned char *salt, 
                int iteration_count,  int hash_idx,
                unsigned char *out,   unsigned long *outlen)
{
   int err;
   unsigned long x;
   hash_state    *md;
   unsigned char *buf;

   LTC_ARGCHK(password != NULL);
   LTC_ARGCHK(salt     != NULL);
   LTC_ARGCHK(out      != NULL);
   LTC_ARGCHK(outlen   != NULL);

   /* test hash IDX */
   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
      return err;
   }

   /* allocate memory */
   md  = XMALLOC(sizeof(hash_state));
   buf = XMALLOC(MAXBLOCKSIZE);
   if (md == NULL || buf == NULL) {
      if (md != NULL) {
         XFREE(md);
      }
      if (buf != NULL) { 
         XFREE(buf);
      }
      return CRYPT_MEM;
   }        

   /* hash initial password + salt */
   if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
       goto LBL_ERR;
   }
   if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) {
       goto LBL_ERR;
   }
   if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) {
       goto LBL_ERR;
   }
   if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
       goto LBL_ERR;
   }

   while (--iteration_count) {
      /* code goes here. */
      x = MAXBLOCKSIZE;
      if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) {
         goto LBL_ERR;
      }
   }

   /* copy upto outlen bytes */
   for (x = 0; x < hash_descriptor[hash_idx].hashsize && x < *outlen; x++) {
       out[x] = buf[x];
   }
   *outlen = x;
   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK 
   zeromem(buf, MAXBLOCKSIZE);
   zeromem(md, sizeof(hash_state));
#endif

   XFREE(buf);
   XFREE(md);

   return err;
}
Esempio n. 8
0
/**
   Terminate an HMAC session
   @param hmac    The HMAC state
   @param out     [out] The destination of the HMAC authentication tag
   @param outlen  [in/out]  The max size and resulting size of the HMAC authentication tag
   @return CRYPT_OK if successful
*/
int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
{
    unsigned char *buf, *isha;
    unsigned long hashsize, i;
    int hash, err;

    LTC_ARGCHK(hmac  != NULL);
    LTC_ARGCHK(out   != NULL);

    /* test hash */
    hash = hmac->hash;
    if((err = hash_is_valid(hash)) != CRYPT_OK) {
        return err;
    }

    /* get the hash message digest size */
    hashsize = hash_descriptor[hash].hashsize;

    /* allocate buffers */
    buf  = XMALLOC(HMAC_BLOCKSIZE);
    isha = XMALLOC(hashsize);
    if (buf == NULL || isha == NULL) { 
       if (buf != NULL) {
          XFREE(buf);
       } 
       if (isha != NULL) {
          XFREE(isha);
       }  
       return CRYPT_MEM;
    }

    /* Get the hash of the first HMAC vector plus the data */
    if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    /* Create the second HMAC vector vector for step (3) */
    for(i=0; i < HMAC_BLOCKSIZE; i++) {
        buf[i] = hmac->key[i] ^ 0x5C;
    }

    /* Now calculate the "outer" hash for step (5), (6), and (7) */
    if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
       goto LBL_ERR;
    }
    if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) {
       goto LBL_ERR;
    }
    if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) {
       goto LBL_ERR;
    }
    if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    /* copy to output  */
    for (i = 0; i < hashsize && i < *outlen; i++) {
        out[i] = buf[i];
    }
    *outlen = i;

    err = CRYPT_OK;
LBL_ERR:
    XFREE(hmac->key);
#ifdef LTC_CLEAN_STACK
    zeromem(isha, hashsize);
    zeromem(buf,  hashsize);
    zeromem(hmac, sizeof(*hmac));
#endif

    XFREE(isha);
    XFREE(buf);

    return err;
}
/**
  Sign a hash with DSA
  @param in       The hash to sign
  @param inlen    The length of the hash to sign
  @param r        The "r" integer of the signature (caller must initialize with mp_init() first)
  @param s        The "s" integer of the signature (caller must initialize with mp_init() first)
  @param prng     An active PRNG state
  @param wprng    The index of the PRNG desired
  @param key      A private DSA key
  @return CRYPT_OK if successful
*/
int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
                                   mp_int *r,   mp_int *s,
                               prng_state *prng, int wprng, dsa_key *key)
{
   mp_int         k, kinv, tmp;
   unsigned char *buf;
   int            err;

   LTC_ARGCHK(in  != NULL);
   LTC_ARGCHK(r   != NULL);
   LTC_ARGCHK(s   != NULL);
   LTC_ARGCHK(key != NULL);

   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
      return err;
   }
   if (key->type != PK_PRIVATE) {
      return CRYPT_PK_NOT_PRIVATE;
   }

   /* check group order size  */
   if (key->qord >= MDSA_MAX_GROUP) {
      return CRYPT_INVALID_ARG;
   }

   buf = XMALLOC(MDSA_MAX_GROUP);
   if (buf == NULL) {
      return CRYPT_MEM;
   }

   /* Init our temps */
   if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != MP_OKAY)               { goto error; }

retry:

   do {
      /* gen random k */
      if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
         err = CRYPT_ERROR_READPRNG;
         goto LBL_ERR;
      }

      /* read k */
      if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY)                { goto error; }

      /* k > 1 ? */
      if (mp_cmp_d(&k, 1) != MP_GT)                                                   { goto retry; }

      /* test gcd */
      if ((err = mp_gcd(&k, &key->q, &tmp)) != MP_OKAY)                               { goto error; }
   } while (mp_cmp_d(&tmp, 1) != MP_EQ);

   /* now find 1/k mod q */
   if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY)                              { goto error; }

   /* now find r = g^k mod p mod q */
   if ((err = mp_exptmod(&key->g, &k, &key->p, r)) != MP_OKAY)                        { goto error; }
   if ((err = mp_mod(r, &key->q, r)) != MP_OKAY)                                      { goto error; }

   if (mp_iszero(r) == MP_YES)                                                        { goto retry; }

   /* now find s = (in + xr)/k mod q */
   if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY)     { goto error; }
   if ((err = mp_mul(&key->x, r, s)) != MP_OKAY)                                      { goto error; }
   if ((err = mp_add(s, &tmp, s)) != MP_OKAY)                                         { goto error; }
   if ((err = mp_mulmod(s, &kinv, &key->q, s)) != MP_OKAY)                            { goto error; }

   if (mp_iszero(s) == MP_YES)                                                        { goto retry; }

   err = CRYPT_OK;
   goto LBL_ERR;

error: 
   err = mpi_to_ltc_error(err);
LBL_ERR: 
   mp_clear_multi(&k, &kinv, &tmp, NULL);
#ifdef LTC_CLEAN_STACK
   zeromem(buf, MDSA_MAX_GROUP);
#endif
   XFREE(buf);
   return err;
}
Esempio n. 10
0
int main(int argc, char *argv[]) {
  FILE *inFile = NULL, *outFile = NULL;
  char inBuf[8192];
  char outFileName[PATH_MAX];
  PRIVATE int c = 0, i, ret;

#ifndef DEBUG
  struct rlimit rlim;

  rlim.rlim_cur = rlim.rlim_max = 0;
  setrlimit( RLIMIT_CORE, &rlim );
#endif

  /* setup config */
  config = ( Config_t * )XMALLOC( sizeof( Config_t ) );
  XMEMSET( config, 0, sizeof( Config_t ) );

  /* force mode to forground */
  config->mode = MODE_INTERACTIVE;

  /* store current pid */
  config->cur_pid = getpid();

  /* get real uid and gid in prep for priv drop */
  config->gid = getgid();
  config->uid = getuid();

  while (1) {
    int this_option_optind = optind ? optind : 1;
#ifdef HAVE_GETOPT_LONG
    int option_index = 0;
    static struct option long_options[] = {
      {"chain", no_argument, 0, 'C' },
      {"cluster", no_argument, 0, 'c' },
      {"greedy", no_argument, 0, 'g' },
      {"version", no_argument, 0, 'v' },
      {"debug", required_argument, 0, 'd' },
      {"help", no_argument, 0, 'h' },
      {"cnum", required_argument, 0, 'n' },
      {"templates", required_argument, 0, 't' },
      {"write", required_argument, 0, 'w' },
      {"match", required_argument, 0, 'm' },
      {"matchfile", required_argument, 0, 'M' },
      {"line", required_argument, 0, 'l' },
      {"linefile", required_argument, 0, 'L' },
      {0, no_argument, 0, 0}
    };
    c = getopt_long(argc, argv, "vd:hn:t:w:cCgm:M:l:L:", long_options, &option_index);
#else
    c = getopt( argc, argv, "vd:htn::w:cCgm:M:l:L:" );
#endif

    if (c EQ -1)
      break;

    switch (c) {

    case 'v':
      /* show the version */
      print_version();
      return( EXIT_SUCCESS );

    case 'c':
      /* enable argument clustering */
      config->cluster = TRUE;
      break;

    case 'C':
      /* enable log chaining */
      config->cluster = TRUE;
      config->chain = TRUE;
      break;
      
    case 'd':
      /* show debig info */
      config->debug = atoi( optarg );
      break;

    case 'g':
      /* ignore quotes */
      config->greedy = TRUE;
      break;

    case 'n':
      /* override default cluster count */
      config->clusterDepth = atoi( optarg );
      break;

    case 't':
      /* load template file */
      if ( loadTemplateFile( optarg ) != TRUE ) {
        fprintf( stderr, "ERR - Problem while loading template file\n" );
        return( EXIT_FAILURE );
      }
      break;

    case 'h':
      /* show help info */
      print_help();
      return( EXIT_SUCCESS );

    case 'w':
      /* save templates to file */
      if ( ( config->outFile_st = fopen( optarg, "w" ) ) EQ NULL ) {
	fprintf( stderr, "ERR - Unable to open template file for write [%s]\n", optarg );
	return( EXIT_FAILURE );
      }
      break;

    case 'M':
      /* load match templates from file */
      config->match = loadMatchTemplates( optarg );
      break;

    case 'm':
      /* add template to match list */
      config->match = addMatchTemplate( optarg );
      break;

    case 'L':
      /* load match lines from file and convert to templates */
      config->match = loadMatchLines( optarg );
      break;

    case 'l':
      /* convert match line and add as template */
      config->match = addMatchLine( optarg );
      break;
	
    default:
      fprintf( stderr, "Unknown option code [0%o]\n", c);
    }
  }

  /* override cluster depth */
  if ( ( config->clusterDepth <= 0 ) | ( config->clusterDepth > 10000 ) )
    config->clusterDepth = MAX_ARGS_IN_FIELD;
  
  /* check dirs and files for danger */

  if ( time( &config->current_time ) EQ -1 ) {
    display( LOG_ERR, "Unable to get current time" );

    /* cleanup buffers */
    cleanup();
    return( EXIT_FAILURE );
  }

  /* initialize program wide config options */
  config->hostname = (char *)XMALLOC( MAXHOSTNAMELEN+1 );

  /* get processor hostname */
  if ( gethostname( config->hostname, MAXHOSTNAMELEN ) != 0 ) {
    display( LOG_ERR, "Unable to get hostname" );
    strcpy( config->hostname, "unknown" );
  }

  config->cur_pid = getpid();

  /* setup current time updater */
  signal( SIGALRM, ctime_prog );
  alarm( ALARM_TIMER );

  /*
   * get to work
   */

  /* process all the files */
  while (optind < argc) {
    processFile( argv[optind++] );
  }

  if ( config->match ) {
    /* XXX should print match metrict */
  } else {
    /* print the templates we have found */
    showTemplates();
  }

  /*
   * finished with the work
   */

  cleanup();

  return( EXIT_SUCCESS );
}
Esempio n. 11
0
/**
  Create a DSA key
  @param prng          An active PRNG state
  @param wprng         The index of the PRNG desired
  @param group_size    Size of the multiplicative group (octets)
  @param modulus_size  Size of the modulus (octets)
  @param key           [out] Where to store the created key
  @return CRYPT_OK if successful, upon error this function will free all allocated memory
*/
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
{
   void           *tmp, *tmp2;
   int            err, res;
   unsigned char *buf;

   LTC_ARGCHK(key  != NULL);
   LTC_ARGCHK(ltc_mp.name != NULL);

   /* check prng */
   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
      return err;
   }

   /* check size */
   if (group_size >= LTC_MDSA_MAX_GROUP || group_size <= 15 || 
       group_size >= modulus_size || (modulus_size - group_size) >= LTC_MDSA_DELTA) {
      return CRYPT_INVALID_ARG;
   }

   /* allocate ram */
   buf = XMALLOC(LTC_MDSA_DELTA);
   if (buf == NULL) {
      return CRYPT_MEM;
   }

   /* init mp_ints  */
   if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
      XFREE(buf);
      return err;
   }

   /* make our prime q */
   if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK)                { goto error; }

   /* double q  */
   if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK)                                { goto error; }

   /* now make a random string and multply it against q */
   if (prng_descriptor[wprng]->read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
      err = CRYPT_ERROR_READPRNG;
      goto error;
   }

   /* force magnitude */
   buf[0] |= 0xC0;

   /* force even */
   buf[modulus_size - group_size - 1] &= ~1;

   if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; }
   if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK)                               { goto error; }
   if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK)                                { goto error; }

   /* now loop until p is prime */
   for (;;) {
       if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK)                     { goto error; }
       if (res == LTC_MP_YES) break;

       /* add 2q to p and 2 to tmp2 */
       if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK)                            { goto error; }
       if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK)                                { goto error; }
   }

   /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */
   mp_set(key->g, 1);

   do {
      if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK)                             { goto error; }
      if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK)                   { goto error; }
   } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ);

   /* at this point tmp generates a group of order q mod p */
   mp_exch(tmp, key->g);

   /* so now we have our DH structure, generator g, order q, modulus p 
      Now we need a random exponent [mod q] and it's power g^x mod p 
    */
   do {
      if (prng_descriptor[wprng]->read(buf, group_size, prng) != (unsigned long)group_size) {
         err = CRYPT_ERROR_READPRNG;
         goto error;
      }
      if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK)           { goto error; }
   } while (mp_cmp_d(key->x, 1) != LTC_MP_GT);
   if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK)                 { goto error; }
  
   key->type = PK_PRIVATE;
   key->qord = group_size;

#ifdef LTC_CLEAN_STACK
   zeromem(buf, LTC_MDSA_DELTA);
#endif

   err = CRYPT_OK;
   goto done;
error: 
    mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
done: 
    mp_clear_multi(tmp, tmp2, NULL);
    XFREE(buf);
    return err;
}
Esempio n. 12
0
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
                                                      buffer* responseBuffer)
{
    OcspEntry*  entry          = NULL;
    CertStatus* status         = NULL;
    byte*       request        = NULL;
    int         requestSz      = 2048;
    byte*       response       = NULL;
    const char* url            = NULL;
    int         urlSz          = 0;
    int         ret            = -1;

#ifdef WOLFSSL_SMALL_STACK
    CertStatus* newStatus;
    OcspResponse* ocspResponse;
#else
    CertStatus newStatus[1];
    OcspResponse ocspResponse[1];
#endif

    WOLFSSL_ENTER("CheckOcspRequest");

    if (responseBuffer) {
        responseBuffer->buffer = NULL;
        responseBuffer->length = 0;
    }

    ret = GetOcspEntry(ocsp, ocspRequest, &entry);
    if (ret != 0)
        return ret;

    ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer);
    if (ret != OCSP_INVALID_STATUS)
        return ret;

    if (ocsp->cm->ocspUseOverrideURL) {
        url = ocsp->cm->ocspOverrideURL;
        if (url != NULL && url[0] != '\0')
            urlSz = (int)XSTRLEN(url);
        else
            return OCSP_NEED_URL;
    }
    else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) {
        url = (const char *)ocspRequest->url;
        urlSz = ocspRequest->urlSz;
    }
    else {
        /* cert doesn't have extAuthInfo, assuming CERT_GOOD */
        return 0;
    }

    request = (byte*)XMALLOC(requestSz, NULL, DYNAMIC_TYPE_OCSP);
    if (request == NULL) {
        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
        return MEMORY_ERROR;
    }

#ifdef WOLFSSL_SMALL_STACK
    newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
                                                       DYNAMIC_TYPE_TMP_BUFFER);
    ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
                                                       DYNAMIC_TYPE_TMP_BUFFER);

    if (newStatus == NULL || ocspResponse == NULL) {
        if (newStatus)    XFREE(newStatus,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);

        XFREE(request, NULL, DYNAMIC_TYPE_OCSP);

        WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
        return MEMORY_E;
    }
#endif

    requestSz = EncodeOcspRequest(ocspRequest, request, requestSz);

    if (ocsp->cm->ocspIOCb)
        ret = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
                                                 request, requestSz, &response);

    if (ret >= 0 && response) {
        XMEMSET(newStatus, 0, sizeof(CertStatus));

        InitOcspResponse(ocspResponse, newStatus, response, ret);
        OcspResponseDecode(ocspResponse, ocsp->cm);

        if (ocspResponse->responseStatus != OCSP_SUCCESSFUL)
            ret = OCSP_LOOKUP_FAIL;
        else {
            if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
                if (responseBuffer) {
                    responseBuffer->buffer = (byte*)XMALLOC(ret, NULL,
                                                       DYNAMIC_TYPE_TMP_BUFFER);

                    if (responseBuffer->buffer) {
                        responseBuffer->length = ret;
                        XMEMCPY(responseBuffer->buffer, response, ret);
                    }
                }

                ret = xstat2err(ocspResponse->status->status);

                if (LockMutex(&ocsp->ocspLock) != 0)
                    ret = BAD_MUTEX_E;
                else {
                    if (status != NULL) {
                        if (status->rawOcspResponse)
                            XFREE(status->rawOcspResponse, NULL,
                                                      DYNAMIC_TYPE_OCSP_STATUS);

                        /* Replace existing certificate entry with updated */
                        XMEMCPY(status, newStatus, sizeof(CertStatus));
                    }
                    else {
                        /* Save new certificate entry */
                        status = (CertStatus*)XMALLOC(sizeof(CertStatus),
                                          NULL, DYNAMIC_TYPE_OCSP_STATUS);
                        if (status != NULL) {
                            XMEMCPY(status, newStatus, sizeof(CertStatus));
                            status->next  = entry->status;
                            entry->status = status;
                            entry->totalStatus++;
                        }
                    }

                    if (status && responseBuffer && responseBuffer->buffer) {
                        status->rawOcspResponse = (byte*)XMALLOC(
                                                   responseBuffer->length, NULL,
                                                   DYNAMIC_TYPE_OCSP_STATUS);

                        if (status->rawOcspResponse) {
                            status->rawOcspResponseSz = responseBuffer->length;
                            XMEMCPY(status->rawOcspResponse,
                                    responseBuffer->buffer,
                                    responseBuffer->length);
                        }
                    }

                    UnLockMutex(&ocsp->ocspLock);
                }
            }
            else
                ret = OCSP_LOOKUP_FAIL;
        }
    }
    else
        ret = OCSP_LOOKUP_FAIL;

#ifdef WOLFSSL_SMALL_STACK
    XFREE(newStatus,    NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    if (response != NULL && ocsp->cm->ocspRespFreeCb)
        ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, response);

    WOLFSSL_LEAVE("CheckOcspRequest", ret);
    return ret;
}
Esempio n. 13
0
int ecc_dp_set_by_oid(ltc_ecc_set_type *dp, unsigned long *oid, unsigned long oidsize)
{
  int i;
  unsigned long len;

  for(i=0; ltc_ecc_sets[i].size != 0; i++) {
    if ((oidsize == ltc_ecc_sets[i].oid.OIDlen) &&
        (XMEM_NEQ(oid, ltc_ecc_sets[i].oid.OID, sizeof(unsigned long) * ltc_ecc_sets[i].oid.OIDlen) == 0)) {
      break;
    }
  }
  if (ltc_ecc_sets[i].size == 0) return CRYPT_INVALID_ARG; /* not found */

  /* a */
  len = (unsigned long)strlen(ltc_ecc_sets[i].A);
  if ((dp->A = XMALLOC(1+len)) == NULL)         goto cleanup1;
  strncpy(dp->A, ltc_ecc_sets[i].A, 1+len);
  /* b */
  len = (unsigned long)strlen(ltc_ecc_sets[i].B);
  if ((dp->B = XMALLOC(1+len)) == NULL)         goto cleanup2;
  strncpy(dp->B, ltc_ecc_sets[i].B, 1+len);
  /* order */
  len = (unsigned long)strlen(ltc_ecc_sets[i].order);
  if ((dp->order = XMALLOC(1+len)) == NULL)     goto cleanup3;
  strncpy(dp->order, ltc_ecc_sets[i].order, 1+len);
  /* prime */
  len = (unsigned long)strlen(ltc_ecc_sets[i].prime);
  if ((dp->prime = XMALLOC(1+len)) == NULL)     goto cleanup4;
  strncpy(dp->prime, ltc_ecc_sets[i].prime, 1+len);
  /* gx */
  len = (unsigned long)strlen(ltc_ecc_sets[i].Gx);
  if ((dp->Gx = XMALLOC(1+len)) == NULL)        goto cleanup5;
  strncpy(dp->Gx, ltc_ecc_sets[i].Gx, 1+len);
  /* gy */
  len = (unsigned long)strlen(ltc_ecc_sets[i].Gy);
  if ((dp->Gy = XMALLOC(1+len)) == NULL)        goto cleanup6;
  strncpy(dp->Gy, ltc_ecc_sets[i].Gy, 1+len);
  /* cofactor & size */
  dp->cofactor = ltc_ecc_sets[i].cofactor;
  dp->size = ltc_ecc_sets[i].size;
  /* name */
  len = (unsigned long)strlen(ltc_ecc_sets[i].name);
  if ((dp->name = XMALLOC(1+len)) == NULL)      goto cleanup7;
  strncpy(dp->name, ltc_ecc_sets[i].name, 1+len);
  /* oid */
  dp->oid.OIDlen = ltc_ecc_sets[i].oid.OIDlen;
  XMEMCPY(dp->oid.OID, ltc_ecc_sets[i].oid.OID, dp->oid.OIDlen * sizeof(dp->oid.OID[0]));
  /* done - success */
  return CRYPT_OK;

cleanup7:
  XFREE(dp->Gy);
cleanup6:
  XFREE(dp->Gx);
cleanup5:
  XFREE(dp->prime);
cleanup4:
  XFREE(dp->order);
cleanup3:
  XFREE(dp->B);
cleanup2:
  XFREE(dp->A);
cleanup1:
  return CRYPT_MEM;
}
Esempio n. 14
0
/* HMAC-KDF with hash type, optional salt and info, return 0 on success */
int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
                   const byte* salt,  word32 saltSz,
                   const byte* info,  word32 infoSz,
                   byte* out,         word32 outSz)
{
    Hmac   myHmac;
#ifdef WOLFSSL_SMALL_STACK
    byte* tmp;
    byte* prk;
#else
    byte   tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */
    byte   prk[MAX_DIGEST_SIZE];
#endif
    const  byte* localSalt;  /* either points to user input or tmp */
    int    hashSz = GetHashSizeByType(type);
    word32 outIdx = 0;
    byte   n = 0x1;
    int    ret;

    if (hashSz < 0)
        return BAD_FUNC_ARG;

#ifdef WOLFSSL_SMALL_STACK
    tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (tmp == NULL)
        return MEMORY_E;

    prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (prk == NULL) {
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return MEMORY_E;
    }
#endif

    localSalt = salt;
    if (localSalt == NULL) {
        XMEMSET(tmp, 0, hashSz);
        localSalt = tmp;
        saltSz    = hashSz;
    }

    do {
    ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz);
    if (ret != 0)
        break;
    ret = wc_HmacUpdate(&myHmac, inKey, inKeySz);
    if (ret != 0)
        break;
    ret = wc_HmacFinal(&myHmac,  prk);
    } while (0);

    if (ret == 0) {
        while (outIdx < outSz) {
            int    tmpSz = (n == 1) ? 0 : hashSz;
            word32 left = outSz - outIdx;

            ret = wc_HmacSetKey(&myHmac, type, prk, hashSz);
            if (ret != 0)
                break;
            ret = wc_HmacUpdate(&myHmac, tmp, tmpSz);
            if (ret != 0)
                break;
            ret = wc_HmacUpdate(&myHmac, info, infoSz);
            if (ret != 0)
                break;
            ret = wc_HmacUpdate(&myHmac, &n, 1);
            if (ret != 0)
                break;
            ret = wc_HmacFinal(&myHmac, tmp);
            if (ret != 0)
                break;

            left = min(left, (word32)hashSz);
            XMEMCPY(out+outIdx, tmp, left);

            outIdx += hashSz;
            n++;
        }
    }

#ifdef WOLFSSL_SMALL_STACK
    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    return ret;
}
Esempio n. 15
0
static int
te_zebra_read_link (int command, struct zclient *zclient, zebra_size_t length)
{
  struct stream *s;
  struct zapi_te_link link;
  s = zclient->ibuf;
  zapi_te_link_read(s, &link);
  switch(command)
    {
      case ZEBRA_TE_LINK_ADD:
{
  TE_LINK *pTeLink;
  COMPONENT_LINK *pComponentLink;
  int ComponentLinksNumber = 1, i, j;
  PATRICIA_PARAMS params;

  if ((pTeLink = (TE_LINK *) XMALLOC (MTYPE_TE, sizeof (TE_LINK))) == NULL)
    {
      zlog_err ("\ncannnot allocate memory");
      return;
    }
  pTeLink->component_links = NULL;
  pTeLink->te_link_id = link->linkid;
  pTeLink->type = PSC_PATH;
  pTeLink->te_link_properties.TeMetric = link->metric;
  pTeLink->te_link_properties.color_mask = link->color_mask;
  pTeLink->te_link_properties.MaxLspBW = link->max_lsp_bw;
  pTeLink->te_link_properties.MaxReservableBW = link->max_res_bw;

  for (j = 0; j < 8; j++)
    pTeLink->te_link_properties.ReservableBW[j] = 0;
  for (i = 0; i < ComponentLinksNumber; i++)
    {
      if ((pComponentLink = new_component_link ()) == NULL)
	{
	  zlog_err ("\ncan initiate component link %s %d", __FILE__,
		    __LINE__);
	  return;
	}
      params.key_size = sizeof (FRR_LABEL_ENTRY);
      params.info_size = 0;
      if (patricia_tree_init (&pComponentLink->ProtectionTree, &params) !=
	  E_OK)
	{
	  zlog_err ("\ncannot initiate patricia tree (per SM) for FRR");
	  return;
	}

      params.key_size = sizeof (PSB_KEY);
      params.info_size = 0;
      if (patricia_tree_init (&pComponentLink->IngressProtectionTree, &params)
	  != E_OK)
	{
	  zlog_err ("\ncannot initiate patricia tree (per SM) for FRR");
	  return;
	}
      pComponentLink->next = pTeLink->component_links;
      pTeLink->component_links = pComponentLink;
      pComponentLink->oifIndex = link->ifindex; /*pTeLink->te_link_id */
      for (j = 0; j < 8; j++)
	{
	  pComponentLink->ReservableBW[j] = link->reservable_bw[j];
	  pComponentLink->ConfiguredReservableBW[j] = link->reservable_bw[j];
	  pTeLink->te_link_properties.ReservableBW[j] +=
	    pComponentLink->ReservableBW[j];
	}
    }

  if (rdb_add_te_link (pTeLink) != E_OK)
    {
      zlog_err ("\nCannot delete TE link");
    }
}
        break;
      case ZEBRA_TE_LINK_DELETE:
  if (rdb_del_te_link (link->linkid) != E_OK)
    {
      zlog_err ("\nCannot delete TE link");
    }
        break;
      case ZEBRA_TE_LINK_UPDATE:
  if (rdb_local_link_status_change (link->linkid, link->status) != E_OK)
    {
      zlog_err ("\nCannot set TE link down");
    }

        break;
    }
}
Esempio n. 16
0
int main(int argc, char **argv) {
  data d;
  glam2_aln *alns;
  int r;

  prog_name = "glam2";  /* for error messages */
  getargs(&d.a, argc, argv);
  init(&d);

  fputs("GLAM2: Gapped Local Alignment of Motifs\nVersion "
#include "glam2_version.h"
	"\n\n", d.out);
  printargs(d.out, argc, argv);
  print_misc_info(d.out, &d);
  putc('\n', d.out);
  XMALLOC(alns, d.a.runs);

  for (r = 0; r < d.a.runs; ++r) {
    glam2_aln *aln = &alns[r];
    if (!d.a.quiet) {
      fprintf(stderr, "Run %d... ", r+1);
      fflush(stderr);
    }
    aln_init(aln, d.seqs.seqnum, d.a.max_width, d.alph.size);
    d.sm.underflow_flag = 1;  /* do we care about underflow in start_aln? */
    start_aln(aln, &d);
    optimise_aln(aln, &d);
    if (d.sm.underflow_flag < (d.a.algorithm == 2 ? DBL_EPSILON : DBL_MIN))
      fprintf(stderr, "%s: accuracy loss due to numeric underflow (%g)\nIf the alignment looks suspect, try rerunning with higher -u, or maybe lower -b\n", prog_name, d.sm.underflow_flag);
    if (d.a.profile)
      print_aln_info(d.out, aln, &d);
  }

  if (!d.a.quiet) putc('\n', stderr);

  SORT(alns, d.a.runs, aln_cmp);
  if (!d.a.profile)
    print_alns(d.out, alns, &d);

  xfclose(d.out);			// close text output file

  // Create the HTML output and MEME format output
  char *glam2html, *glam2psfm, *command;
  int command_length, command_ret;
  // create the paths to the programs
  glam2html = make_path_to_file(get_meme_bin_dir(), "glam2html");
  glam2psfm = make_path_to_file(get_meme_bin_dir(), "glam2psfm");
  // allocate memory for the command
  command_length = strlen(glam2html) + strlen(d.txt_filename) + strlen(d.html_filename) + 50;
  command = xmalloc(command_length);
  // run glam2html
  sprintf(command, "%s < %s > %s",  glam2html, d.txt_filename, d.html_filename);
  if ((command_ret = system(command)) != 0) {
    report_external_failure("glam2html", command_ret);
    fprintf(stderr, "Warning: failed to convert output to HTML!\n");
  }
  // run glam2psfm
  sprintf(command, "%s < %s > %s", glam2psfm, d.txt_filename, d.psfm_filename);
  if ((command_ret = system(command)) != 0) {
    report_external_failure("glam2psfm", command_ret);
    fprintf(stderr, "Warning: failed to convert output to MEME format motif!\n");
  }
  free(command);
  free(glam2psfm);
  free(glam2html);

  return 0;
}
/**
  Decrypt an ECC encrypted key
  @param in       The ciphertext
  @param inlen    The length of the ciphertext (octets)
  @param out      [out] The plaintext
  @param outlen   [in/out] The max size and resulting size of the plaintext
  @param key      The corresponding private ECC key
  @return CRYPT_OK if successful
*/
int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
                          unsigned char *out, unsigned long *outlen, 
                          ecc_key *key)
{
   unsigned char *ecc_shared, *skey, *pub_expt;
   unsigned long  x, y, hashOID[32];
   int            hash, err;
   ecc_key        pubkey;
   ltc_asn1_list  decode[3];

   LTC_ARGCHK(in     != NULL);
   LTC_ARGCHK(out    != NULL);
   LTC_ARGCHK(outlen != NULL);
   LTC_ARGCHK(key    != NULL);

   /* right key type? */
   if (key->type != PK_PRIVATE) {
      return CRYPT_PK_NOT_PRIVATE;
   }
   
   /* decode to find out hash */
   LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
 
   if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
      return err;
   }
   for (hash = 0; hash_descriptor[hash].name   != NULL             && 
                  (hash_descriptor[hash].OIDlen != decode[0].size   || 
                   memcmp(hash_descriptor[hash].OID, hashOID, sizeof(unsigned long)*decode[0].size)); hash++);

   if (hash_descriptor[hash].name == NULL) {
      return CRYPT_INVALID_PACKET;
   }

   /* we now have the hash! */

   /* allocate memory */
   pub_expt   = XMALLOC(ECC_BUF_SIZE);
   ecc_shared = XMALLOC(ECC_BUF_SIZE);
   skey       = XMALLOC(MAXBLOCKSIZE);
   if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
      if (pub_expt != NULL) {
         XFREE(pub_expt);
      }
      if (ecc_shared != NULL) {
         XFREE(ecc_shared);
      }
      if (skey != NULL) {
         XFREE(skey);
      }
      return CRYPT_MEM;
   }
   LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING,      pub_expt,  ECC_BUF_SIZE);
   LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING,      skey,      MAXBLOCKSIZE);

   /* read the structure in now */
   if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   /* import ECC key from packet */
   if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   /* make shared key */
   x = ECC_BUF_SIZE;
   if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
      ecc_free(&pubkey);
      goto LBL_ERR;
   }
   ecc_free(&pubkey);

   y = MAXBLOCKSIZE;
   if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   /* ensure the hash of the shared secret is at least as big as the encrypt itself */
   if (decode[2].size > y) {
      err = CRYPT_INVALID_PACKET;
      goto LBL_ERR;
   }

   /* avoid buffer overflow */
   if (*outlen < decode[2].size) {
      err = CRYPT_BUFFER_OVERFLOW;
      goto LBL_ERR;
   }

   /* Decrypt the key */
   for (x = 0; x < decode[2].size; x++) {
     out[x] = skey[x] ^ ecc_shared[x];
   }
   *outlen = x;

   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(pub_expt,   ECC_BUF_SIZE);
   zeromem(ecc_shared, ECC_BUF_SIZE);
   zeromem(skey,       MAXBLOCKSIZE);
#endif

   XFREE(pub_expt);
   XFREE(ecc_shared);
   XFREE(skey);

   return err;
}
Esempio n. 18
0
static int
interface_list_ioctl (int af)
{
  int ret;
  int sock;
#define IFNUM_BASE 32
  struct lifnum lifn;
  int ifnum;
  struct lifreq *lifreq;
  struct lifconf lifconf;
  struct interface *ifp;
  int n;
  int save_errno;
  size_t needed, lastneeded = 0;
  char *buf = NULL;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");
  
  sock = socket (af, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      zlog_warn ("Can't make %s socket stream: %s",
                 (af == AF_INET ? "AF_INET" : "AF_INET6"), safe_strerror (errno));
                 
      if (zserv_privs.change(ZPRIVS_LOWER))
        zlog (NULL, LOG_ERR, "Can't lower privileges");
        
      return -1;
    }

calculate_lifc_len:     /* must hold privileges to enter here */
  lifn.lifn_family = af;
  lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */
  ret = ioctl (sock, SIOCGLIFNUM, &lifn);
  save_errno = errno;
  
  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");
 
  if (ret < 0)
    {
      zlog_warn ("interface_list_ioctl: SIOCGLIFNUM failed %s",
                 safe_strerror (save_errno));
      close (sock);
      return -1;
    }
  ifnum = lifn.lifn_count;

  /*
   * When calculating the buffer size needed, add a small number
   * of interfaces to those we counted.  We do this to capture
   * the interface status of potential interfaces which may have
   * been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF.
   */
  needed = (ifnum + 4) * sizeof (struct lifreq);
  if (needed > lastneeded || needed < lastneeded / 2)
    {
      if (buf != NULL)
        XFREE (MTYPE_TMP, buf);
      if ((buf = XMALLOC (MTYPE_TMP, needed)) == NULL)
        {
          zlog_warn ("interface_list_ioctl: malloc failed");
          close (sock);
          return -1;
        }
    }
  lastneeded = needed;

  lifconf.lifc_family = af;
  lifconf.lifc_flags = LIFC_NOXMIT;
  lifconf.lifc_len = needed;
  lifconf.lifc_buf = buf;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");
    
  ret = ioctl (sock, SIOCGLIFCONF, &lifconf);

  if (ret < 0)
    {
      if (errno == EINVAL)
        goto calculate_lifc_len; /* deliberately hold privileges */

      zlog_warn ("SIOCGLIFCONF: %s", safe_strerror (errno));

      if (zserv_privs.change(ZPRIVS_LOWER))
        zlog (NULL, LOG_ERR, "Can't lower privileges");

      goto end;
    }

  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");
    
  /* Allocate interface. */
  lifreq = lifconf.lifc_req;

  for (n = 0; n < lifconf.lifc_len; n += sizeof (struct lifreq))
    {
      /* we treat Solaris logical interfaces as addresses, because that is
       * how PF_ROUTE on Solaris treats them. Hence we can not directly use
       * the lifreq_name to get the ifp.  We need to normalise the name
       * before attempting get.
       *
       * Solaris logical interface names are in the form of:
       * <interface name>:<logical interface id>
       */
      unsigned int normallen = 0;
      uint64_t lifflags;
      
      /* We should exclude ~IFF_UP interfaces, as we'll find out about them
       * coming up later through RTM_NEWADDR message on the route socket.
       */
      if (if_get_flags_direct (lifreq->lifr_name, &lifflags,
                           lifreq->lifr_addr.ss_family)
          || !CHECK_FLAG (lifflags, IFF_UP))
        {
          lifreq++;
          continue;
        }
      
      /* Find the normalised name */
      while ( (normallen < sizeof(lifreq->lifr_name))
             && ( *(lifreq->lifr_name + normallen) != '\0')
             && ( *(lifreq->lifr_name + normallen) != ':') )
        normallen++;
      
      ifp = if_get_by_name_len(lifreq->lifr_name, normallen);

      if (lifreq->lifr_addr.ss_family == AF_INET)
        ifp->flags |= IFF_IPV4;

      if (lifreq->lifr_addr.ss_family == AF_INET6)
        {
#ifdef HAVE_IPV6
          ifp->flags |= IFF_IPV6;
#else
          lifreq++;
          continue;
#endif /* HAVE_IPV6 */
        }
        
      if_add_update (ifp);

      interface_info_ioctl (ifp);
      
      /* If a logical interface pass the full name so it can be
       * as a label on the address
       */
      if ( *(lifreq->lifr_name + normallen) != '\0')
        if_get_addr (ifp, (struct sockaddr *) &lifreq->lifr_addr,
                     lifreq->lifr_name);
      else
        if_get_addr (ifp, (struct sockaddr *) &lifreq->lifr_addr, NULL);
        
      /* Poke the interface flags. Lets IFF_UP mangling kick in */
      if_flags_update (ifp, ifp->flags);
      
      lifreq++;
    }

end:
  close (sock);
  XFREE (MTYPE_TMP, lifconf.lifc_buf);
  return ret;
}
/**
   Perform PKCS #1 MGF1 (internal)
   @param seed        The seed for MGF1
   @param seedlen     The length of the seed
   @param hash_idx    The index of the hash desired
   @param mask        [out] The destination
   @param masklen     The length of the mask desired
   @return CRYPT_OK if successful
*/
int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen,
                      int            hash_idx,
                      unsigned char *mask, unsigned long masklen)
{
   unsigned long hLen, x;
   ulong32       counter;
   int           err;
   hash_state    *md;
   unsigned char *buf;
 
   LTC_ARGCHK(seed != NULL);
   LTC_ARGCHK(mask != NULL);

   /* ensure valid hash */
   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { 
      return err;
   }

   /* get hash output size */
   hLen = hash_descriptor[hash_idx].hashsize;

   /* allocate memory */
   md  = XMALLOC(sizeof(hash_state));
   buf = XMALLOC(hLen);
   if (md == NULL || buf == NULL) {
      if (md != NULL) {
         XFREE(md);
      }
      if (buf != NULL) {
         XFREE(buf);
      }
      return CRYPT_MEM;
   }

   /* start counter */
   counter = 0;

   while (masklen > 0) {
       /* handle counter */
       STORE32H(counter, buf);
       ++counter;

       /* get hash of seed || counter */
       if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) {
          goto LBL_ERR;
       }
       if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
          goto LBL_ERR;
       }

       /* store it */
       for (x = 0; x < hLen && masklen > 0; x++, masklen--) {
          *mask++ = buf[x];
       }
   }

   err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(buf, hLen);
   zeromem(md,  sizeof(hash_state));
#endif

   XFREE(buf);
   XFREE(md);

   return err;
}
Esempio n. 20
0
/**
   f9 a file
   @param cipher   The index of the cipher desired
   @param key      The secret key
   @param keylen   The length of the secret key (octets)
   @param fname    The name of the file you wish to f9
   @param out      [out] Where the authentication tag is to be stored
   @param outlen   [in/out] The max size and resulting size of the authentication tag
   @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
*/
int f9_file(int cipher,
              const unsigned char *key, unsigned long keylen,
              const char *fname,
                    unsigned char *out, unsigned long *outlen)
{
#ifdef LTC_NO_FILE
   LTC_UNUSED_PARAM(cipher);
   LTC_UNUSED_PARAM(key);
   LTC_UNUSED_PARAM(keylen);
   LTC_UNUSED_PARAM(fname);
   LTC_UNUSED_PARAM(out);
   LTC_UNUSED_PARAM(outlen);
   return CRYPT_NOP;
#else
   size_t x;
   int err;
   f9_state f9;
   FILE *in;
   unsigned char *buf;

   LTC_ARGCHK(key    != NULL);
   LTC_ARGCHK(fname  != NULL);
   LTC_ARGCHK(out    != NULL);
   LTC_ARGCHK(outlen != NULL);

   if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
      return CRYPT_MEM;
   }

   if ((err = f9_init(&f9, cipher, key, keylen)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   in = fopen(fname, "rb");
   if (in == NULL) {
      err = CRYPT_FILE_NOTFOUND;
      goto LBL_ERR;
   }

   do {
      x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
      if ((err = f9_process(&f9, buf, (unsigned long)x)) != CRYPT_OK) {
         fclose(in);
         goto LBL_CLEANBUF;
      }
   } while (x == LTC_FILE_READ_BUFSIZE);

   if (fclose(in) != 0) {
      err = CRYPT_ERROR;
      goto LBL_CLEANBUF;
   }

   err = f9_done(&f9, out, outlen);

LBL_CLEANBUF:
   zeromem(buf, LTC_FILE_READ_BUFSIZE);
LBL_ERR:
#ifdef LTC_CLEAN_STACK
   zeromem(&f9, sizeof(f9_state));
#endif
   XFREE(buf);
   return err;
#endif
}
Esempio n. 21
0
/**
   Initialize an HMAC context.
   @param hmac     The HMAC state 
   @param hash     The index of the hash you want to use 
   @param key      The secret key
   @param keylen   The length of the secret key (octets)
   @return CRYPT_OK if successful
*/
int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
{
    unsigned char *buf;
    unsigned long hashsize;
    unsigned long i, z;
    int err;

    LTC_ARGCHK(hmac != NULL);
    LTC_ARGCHK(key  != NULL);

    /* valid hash? */
    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
        return err;
    }
    hmac->hash = hash;
    hashsize   = hash_descriptor[hash].hashsize;

    /* valid key length? */
    if (keylen == 0) {
        return CRYPT_INVALID_KEYSIZE;
    }

    /* allocate ram for buf */
    buf = XMALLOC(HMAC_BLOCKSIZE);
    if (buf == NULL) {
       return CRYPT_MEM;
    }

    /* allocate memory for key */
    hmac->key = XMALLOC(HMAC_BLOCKSIZE);
    if (hmac->key == NULL) {
       XFREE(buf);
       return CRYPT_MEM;
    }

    /* (1) make sure we have a large enough key */
    if(keylen > HMAC_BLOCKSIZE) {
        z = HMAC_BLOCKSIZE;
        if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
           goto LBL_ERR;
        }
        if(hashsize < HMAC_BLOCKSIZE) {
            zeromem((hmac->key) + hashsize, (size_t)(HMAC_BLOCKSIZE - hashsize));
        }
        keylen = hashsize;
    } else {
        XMEMCPY(hmac->key, key, (size_t)keylen);
        if(keylen < HMAC_BLOCKSIZE) {
            zeromem((hmac->key) + keylen, (size_t)(HMAC_BLOCKSIZE - keylen));
        }
    }

    /* Create the initial vector for step (3) */
    for(i=0; i < HMAC_BLOCKSIZE;   i++) {
       buf[i] = hmac->key[i] ^ 0x36;
    }

    /* Pre-pend that to the hash data */
    if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) {
       goto LBL_ERR;
    }

    if ((err = hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE)) != CRYPT_OK) {
       goto LBL_ERR;
    }
    goto done;
LBL_ERR:
    /* free the key since we failed */
    XFREE(hmac->key);
done:
#ifdef LTC_CLEAN_STACK
   zeromem(buf, HMAC_BLOCKSIZE);
#endif
 
   XFREE(buf);
   return err;    
}
Esempio n. 22
0
/* Load CRL File of type, SSL_SUCCESS on ok */
int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type)
{
    int          ret = SSL_SUCCESS;
    const byte*  myBuffer = buff;    /* if DER ok, otherwise switch */
    DerBuffer*   der = NULL;
#ifdef WOLFSSL_SMALL_STACK
    DecodedCRL*  dcrl;
#else
    DecodedCRL   dcrl[1];
#endif

    WOLFSSL_ENTER("BufferLoadCRL");

    if (crl == NULL || buff == NULL || sz == 0)
        return BAD_FUNC_ARG;

    if (type == SSL_FILETYPE_PEM) {
        int eccKey = 0;   /* not used */
        EncryptedInfo info;
        info.ctx = NULL;

        ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey);
        if (ret == 0) {
            myBuffer = der->buffer;
            sz = der->length;
        }
        else {
            WOLFSSL_MSG("Pem to Der failed");
            FreeDer(&der);
            return -1;
        }
    }

#ifdef WOLFSSL_SMALL_STACK
    dcrl = (DecodedCRL*)XMALLOC(sizeof(DecodedCRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (dcrl == NULL) {
        FreeDer(&der);
        return MEMORY_E;
    }
#endif

    InitDecodedCRL(dcrl, crl->heap);
    ret = ParseCRL(dcrl, myBuffer, (word32)sz, crl->cm);
    if (ret != 0) {
        WOLFSSL_MSG("ParseCRL error");
    }
    else {
        ret = AddCRL(crl, dcrl);
        if (ret != 0) {
            WOLFSSL_MSG("AddCRL error");
        }
    }

    FreeDecodedCRL(dcrl);

#ifdef WOLFSSL_SMALL_STACK
    XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    FreeDer(&der);

    return ret ? ret : SSL_SUCCESS; /* convert 0 to SSL_SUCCESS */
}
Esempio n. 23
0
/*
 * This is the parent kcgi process.
 * It spins on input from the child until all fields have been received.
 * These fields are sent from the child's output() function.
 * Each input field consists of the data and its validation state.
 * We build up the kpair arrays here with this data, then assign the
 * kpairs into named buckets.
 */
enum kcgi_err
kworker_parent(int fd, struct kreq *r, int eofok)
{
	struct kpair	 kp;
	struct kpair	*kpp;
	enum krequ	 requ;
	enum input	 type;
	int		 rc;
	enum kcgi_err	 ke;
	size_t		 i, dgsz;

	/* Pointers freed at "out" label. */
	memset(&kp, 0, sizeof(struct kpair));

	/*
	 * First read all of our parsed parameters.
	 * Each parsed parameter is handled a little differently.
	 * This list will end with META__MAX.
	 */
	if (fullread(fd, &r->reqsz, sizeof(size_t), 0, &ke) < 0) {
		XWARNX("failed to read request header size");
		goto out;
	}
	r->reqs = XCALLOC(r->reqsz, sizeof(struct khead));
	if (NULL == r->reqs) {
		ke = KCGI_ENOMEM;
		goto out;
	}
	for (i = 0; i < r->reqsz; i++) {
		if (fullread(fd, &requ, sizeof(enum krequ), 0, &ke) < 0) {
			XWARNX("failed to read request identifier");
			goto out;
		}
		if (KCGI_OK != (ke = fullreadword(fd, &r->reqs[i].key))) {
			XWARNX("failed to read request key");
			goto out;
		}
		if (KCGI_OK != (ke = fullreadword(fd, &r->reqs[i].val))) {
			XWARNX("failed to read request value");
			goto out;
		}
		if (requ != KREQU__MAX)
			r->reqmap[requ] = &r->reqs[i];
	}

	if (fullread(fd, &r->method, sizeof(enum kmethod), 0, &ke) < 0) {
		XWARNX("failed to read request method");
		goto out;
	} else if (fullread(fd, &r->auth, sizeof(enum kauth), 0, &ke) < 0) {
		XWARNX("failed to read authorisation type");
		goto out;
	} else if (KCGI_OK != (ke = kworker_auth_parent(fd, &r->rawauth))) {
		XWARNX("failed to read raw authorisation");
		goto out;
	} else if (fullread(fd, &r->scheme, sizeof(enum kscheme), 0, &ke) < 0) {
		XWARNX("failed to read scheme");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->remote))) {
		XWARNX("failed to read remote");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->fullpath))) {
		XWARNX("failed to read fullpath");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->suffix))) {
		XWARNX("failed to read suffix");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->pagename))) {
		XWARNX("failed to read page part");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->path))) {
		XWARNX("failed to read path part");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->pname))) {
		XWARNX("failed to read script name");
		goto out;
	} else if (KCGI_OK != (ke = fullreadword(fd, &r->host))) {
		XWARNX("failed to read host name");
		goto out;
	} else if (fullread(fd, &r->port, sizeof(uint16_t), 0, &ke) < 0) {
		XWARNX("failed to read port");
		goto out;
	} else if (fullread(fd, &dgsz, sizeof(size_t), 0, &ke) < 0) {
		XWARNX("failed to read digest length");
		goto out;
	} else if (MD5_DIGEST_LENGTH == dgsz) {
		/* This is a binary value. */
		if (NULL == (r->rawauth.digest = XMALLOC(dgsz)))
			goto out;
		if (fullread(fd, r->rawauth.digest, dgsz, 0, &ke) < 0) {
			XWARNX("failed to read digest");
			goto out;
		}
	}

	while ((rc = input(&type, &kp, fd, &ke, eofok)) > 0) {
		assert(type < IN__MAX);
		/*
		 * We have a parsed field from the child process.
		 * Begin by expanding the number of parsed fields
		 * depending on whether we have a cookie or form input.
		 * Then copy the new data.
		 */
		kpp = IN_COOKIE == type ?
			kpair_expand(&r->cookies, &r->cookiesz) :
			kpair_expand(&r->fields, &r->fieldsz);

		if (NULL == kpp) {
			rc = -1;
			ke = KCGI_ENOMEM;
			break;
		}

		*kpp = kp;
	}

	if (rc < 0)
		goto out;

	/*
	 * Now that the field and cookie arrays are fixed and not going
	 * to be reallocated any more, we run through both arrays and
	 * assign the named fields into buckets.
	 */
	for (i = 0; i < r->fieldsz; i++) {
		kpp = &r->fields[i];
		if (kpp->keypos == r->keysz)
			continue;
		if (KPAIR_INVALID != kpp->state) {
			kpp->next = r->fieldmap[kpp->keypos];
			r->fieldmap[kpp->keypos] = kpp;
		} else {
			kpp->next = r->fieldnmap[kpp->keypos];
			r->fieldnmap[kpp->keypos] = kpp;
		}
	}
	for (i = 0; i < r->cookiesz; i++) {
		kpp = &r->cookies[i];
		if (kpp->keypos == r->keysz)
			continue;
		if (KPAIR_INVALID != kpp->state) {
			kpp->next = r->cookiemap[kpp->keypos];
			r->cookiemap[kpp->keypos] = kpp;
		} else {
			kpp->next = r->cookienmap[kpp->keypos];
			r->cookienmap[kpp->keypos] = kpp;
		}
	}

	ke = KCGI_OK;
	/*
	 * Usually, "kp" would be zeroed after its memory is copied into
	 * one of the form-input arrays.
	 * However, in the case of error, these may still have
	 * allocations, so free them now.
	 */
out:
	free(kp.key);
	free(kp.val);
	free(kp.file);
	free(kp.ctype);
	free(kp.xcode);
	return(ke);
}
Esempio n. 24
0
/* read in new CRL entries and save new list */
static int SwapLists(WOLFSSL_CRL* crl)
{
    int        ret;
    CRL_Entry* newList;
#ifdef WOLFSSL_SMALL_STACK
    WOLFSSL_CRL* tmp;
#else
    WOLFSSL_CRL tmp[1];
#endif

#ifdef WOLFSSL_SMALL_STACK
    tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (tmp == NULL)
        return MEMORY_E;
#endif

    if (InitCRL(tmp, crl->cm) < 0) {
        WOLFSSL_MSG("Init tmp CRL failed");
#ifdef WOLFSSL_SMALL_STACK
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
        return -1;
    }

    if (crl->monitors[0].path) {
        ret = LoadCRL(tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0);
        if (ret != SSL_SUCCESS) {
            WOLFSSL_MSG("PEM LoadCRL on dir change failed");
            FreeCRL(tmp, 0);
#ifdef WOLFSSL_SMALL_STACK
            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
            return -1;
        }
    }

    if (crl->monitors[1].path) {
        ret = LoadCRL(tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0);
        if (ret != SSL_SUCCESS) {
            WOLFSSL_MSG("DER LoadCRL on dir change failed");
            FreeCRL(tmp, 0);
#ifdef WOLFSSL_SMALL_STACK
            XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
            return -1;
        }
    }

    if (wc_LockMutex(&crl->crlLock) != 0) {
        WOLFSSL_MSG("wc_LockMutex failed");
        FreeCRL(tmp, 0);
#ifdef WOLFSSL_SMALL_STACK
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
        return -1;
    }

    newList = tmp->crlList;

    /* swap lists */
    tmp->crlList  = crl->crlList;
    crl->crlList = newList;

    wc_UnLockMutex(&crl->crlLock);

    FreeCRL(tmp, 0);

#ifdef WOLFSSL_SMALL_STACK
    XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    return 0;
}
Esempio n. 25
0
/* return: >0 OCSP Response Size
 *         -1 error */
static int process_http_response(int sfd, byte** respBuf,
                                                  byte* httpBuf, int httpBufSz)
{
    int result;
    int len = 0;
    char *start, *end;
    byte *recvBuf = NULL;
    int recvBufSz = 0;
    enum phr_state { phr_init, phr_http_start, phr_have_length,
                     phr_have_type, phr_wait_end, phr_http_end
    } state = phr_init;

    start = end = NULL;
    do {
        if (end == NULL) {
            result = (int)RECV_FUNCTION(sfd, (char*)httpBuf+len, httpBufSz-len-1, 0);
            if (result > 0) {
                len += result;
                start = (char*)httpBuf;
                start[len] = 0;
            }
            else {
                WOLFSSL_MSG("process_http_response recv http from peer failed");
                return -1;
            }
        }
        end = XSTRSTR(start, "\r\n");

        if (end == NULL) {
            if (len != 0)
                XMEMMOVE(httpBuf, start, len);
            start = end = NULL;
        }
        else if (end == start) {
            if (state == phr_wait_end) {
                state = phr_http_end;
                len -= 2;
                start += 2;
             }
             else {
                WOLFSSL_MSG("process_http_response header ended early");
                return -1;
             }
        }
        else {
            *end = 0;
            len -= (int)(end - start) + 2;
                /* adjust len to remove the first line including the /r/n */

            if (XSTRNCASECMP(start, "HTTP/1", 6) == 0) {
                start += 9;
                if (XSTRNCASECMP(start, "200 OK", 6) != 0 ||
                                                           state != phr_init) {
                    WOLFSSL_MSG("process_http_response not OK");
                    return -1;
                }
                state = phr_http_start;
            }
            else if (XSTRNCASECMP(start, "Content-Type:", 13) == 0) {
                start += 13;
                while (*start == ' ' && *start != '\0') start++;
                if (XSTRNCASECMP(start, "application/ocsp-response", 25) != 0) {
                    WOLFSSL_MSG("process_http_response not ocsp-response");
                    return -1;
                }
                
                if (state == phr_http_start) state = phr_have_type;
                else if (state == phr_have_length) state = phr_wait_end;
                else {
                    WOLFSSL_MSG("process_http_response type invalid state");
                    return -1;
                }
            }
            else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) {
                start += 15;
                while (*start == ' ' && *start != '\0') start++;
                recvBufSz = atoi(start);

                if (state == phr_http_start) state = phr_have_length;
                else if (state == phr_have_type) state = phr_wait_end;
                else {
                    WOLFSSL_MSG("process_http_response length invalid state");
                    return -1;
                }
            }
            
            start = end + 2;
        }
    } while (state != phr_http_end);

    recvBuf = (byte*)XMALLOC(recvBufSz, NULL, DYNAMIC_TYPE_OCSP);
    if (recvBuf == NULL) {
        WOLFSSL_MSG("process_http_response couldn't create response buffer");
        return -1;
    }

    /* copy the remainder of the httpBuf into the respBuf */
    if (len != 0)
        XMEMCPY(recvBuf, start, len);

    /* receive the OCSP response data */
    do {
        result = (int)RECV_FUNCTION(sfd, (char*)recvBuf+len, recvBufSz-len, 0);
        if (result > 0)
            len += result;
        else {
            WOLFSSL_MSG("process_http_response recv ocsp from peer failed");
            return -1;
        }
    } while (len != recvBufSz);

    *respBuf = recvBuf;
    return recvBufSz;
}
Esempio n. 26
0
/* linux monitoring */
static void* DoMonitor(void* arg)
{
    int         notifyFd;
    int         wd  = -1;
    WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg;
#ifdef WOLFSSL_SMALL_STACK
    char*       buff;
#else
    char        buff[8192];
#endif

    WOLFSSL_ENTER("DoMonitor");

    crl->mfd = eventfd(0, 0);  /* our custom shutdown event */
    if (crl->mfd < 0) {
        WOLFSSL_MSG("eventfd failed");
        SignalSetup(crl, MONITOR_SETUP_E);
        return NULL;
    }

    notifyFd = inotify_init();
    if (notifyFd < 0) {
        WOLFSSL_MSG("inotify failed");
        close(crl->mfd);
        SignalSetup(crl, MONITOR_SETUP_E);
        return NULL;
    }

    if (crl->monitors[0].path) {
        wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
                                                                IN_DELETE);
        if (wd < 0) {
            WOLFSSL_MSG("PEM notify add watch failed");
            close(crl->mfd);
            close(notifyFd);
            SignalSetup(crl, MONITOR_SETUP_E);
            return NULL;
        }
    }

    if (crl->monitors[1].path) {
        wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
                                                                IN_DELETE);
        if (wd < 0) {
            WOLFSSL_MSG("DER notify add watch failed");
            close(crl->mfd);
            close(notifyFd);
            SignalSetup(crl, MONITOR_SETUP_E);
            return NULL;
        }
    }

#ifdef WOLFSSL_SMALL_STACK
    buff = (char*)XMALLOC(8192, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (buff == NULL)
        return NULL;
#endif

    /* signal to calling thread we're setup */
    if (SignalSetup(crl, 1) != 0) {
        #ifdef WOLFSSL_SMALL_STACK
            XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        #endif

        if (wd > 0)
            inotify_rm_watch(notifyFd, wd);
        close(crl->mfd);
        close(notifyFd);
        return NULL;
    }

    for (;;) {
        fd_set readfds;
        int    result;
        int    length;

        FD_ZERO(&readfds);
        FD_SET(notifyFd, &readfds);
        FD_SET(crl->mfd, &readfds);

        result = select(max(notifyFd, crl->mfd) + 1, &readfds, NULL, NULL,NULL);

        WOLFSSL_MSG("Got notify event");

        if (result < 0) {
            WOLFSSL_MSG("select problem, continue");
            continue;
        }

        if (FD_ISSET(crl->mfd, &readfds)) {
            WOLFSSL_MSG("got custom shutdown event, breaking out");
            break;
        }

        length = (int) read(notifyFd, buff, 8192);
        if (length < 0) {
            WOLFSSL_MSG("notify read problem, continue");
            continue;
        }

        if (SwapLists(crl) < 0) {
            WOLFSSL_MSG("SwapLists problem, continue");
        }
    }

#ifdef WOLFSSL_SMALL_STACK
    XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    if (wd > 0)
        inotify_rm_watch(notifyFd, wd);
    close(crl->mfd);
    close(notifyFd);

    return NULL;
}
Esempio n. 27
0
  Symbol* Converter::primitive_convert(STATE, Object* source, String* target,
                                       Fixnum* offset, Fixnum* size, Fixnum* options) {
    String* src = 0;

    if(!source->nil_p()) {
      if(!(src = try_as<String>(source))) {
        return force_as<Symbol>(Primitives::failure());
      }
    }

    Converter* self = this;
    OnStack<4> os(state, self, source, src, target);

    const unsigned char* source_ptr = 0;
    const unsigned char* source_end = 0;

    native_int byte_offset = offset->to_native();
    native_int byte_size = size->to_native();

  retry:

    if(!self->converter_) {
      size_t num_converters = self->converters()->size();

      self->set_converter(rb_econv_alloc(num_converters));

      for(size_t i = 0; i < num_converters; i++) {
        Transcoding* transcoding = as<Transcoding>(self->converters()->get(state, i));
        rb_transcoder* tr = transcoding->get_transcoder();

        if(rb_econv_add_transcoder_at(self->converter_, tr, i) == -1) {
          rb_econv_free(self->get_converter());
          self->set_converter(NULL);
          return force_as<Symbol>(Primitives::failure());
        }
      }
    }

    /* It would be nice to have a heuristic that avoids having to reconvert
     * after growing the destination buffer. This is complicated, however, as
     * a converter may contain more than one transcoder. So, the heuristic
     * would need to be transitive. This requires getting the encoding objects
     * for every stage of the converter to check the min/max byte values.
     */
    if(byte_size == -1) {
      byte_size = src ? src->byte_size() : 4096;
    }

    int flags = self->converter_->flags = options->to_native();

    if(!self->replacement()->nil_p() && !self->converter_->replacement_str) {
      // First check the array's whether they exist so we don't
      // leak memory or create badly initialized C structures

      size_t num_converters = self->replacement_converters()->size();

      for(size_t i = 0, k = 0; i < num_converters; k++, i += 2) {
        as<String>(self->replacement_converters()->get(state, i));
        as<Array>(self->replacement_converters()->get(state, i + 1));
      }

      native_int byte_size = self->replacement()->byte_size();
      char* buf = (char*)XMALLOC(byte_size + 1);
      strncpy(buf, self->replacement()->c_str(state), byte_size + 1);
      self->converter_->replacement_str = (const unsigned char*)buf;
      self->converter_->replacement_len = self->replacement()->byte_size();

      String* name = self->replacement()->encoding()->name();
      byte_size = name->byte_size();
      buf = (char*)XMALLOC(byte_size + 1);
      strncpy(buf, name->c_str(state), byte_size + 1);
      self->converter_->replacement_enc = (const char*)buf;
      self->converter_->replacement_allocated = 1;

      rb_econv_alloc_replacement_converters(self->converter_, num_converters / 2);

      for(size_t i = 0, k = 0; i < num_converters; k++, i += 2) {
        rb_econv_replacement_converters* repl_converter;
        repl_converter = self->converter_->replacement_converters + k;

        // We can use force_as here since we know type has been checked above
        name = force_as<String>(self->replacement_converters()->get(state, i));
        byte_size = name->byte_size();
        buf = (char*)XMALLOC(byte_size + 1);
        strncpy(buf, name->c_str(state), byte_size + 1);
        repl_converter->destination_encoding_name = (const char*)buf;

        Array* trs = force_as<Array>(replacement_converters()->get(state, i + 1));

        size_t num_transcoders = trs->size();

        repl_converter->num_transcoders = num_transcoders;
        repl_converter->transcoders = ALLOC_N(rb_transcoder*, num_transcoders);

        for(size_t j = 0; j < num_transcoders; j++) {
          Transcoding* transcoding = as<Transcoding>(trs->get(state, j));
          rb_transcoder* tr = transcoding->get_transcoder();

          repl_converter->transcoders[j] = tr;
        }
      }
    }
Esempio n. 28
0
/* Load CRL path files of type, SSL_SUCCESS on ok */
int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
{
    struct dirent* entry;
    DIR*           dir;
    int            ret = SSL_SUCCESS;
#ifdef WOLFSSL_SMALL_STACK
    char*          name;
#else
    char           name[MAX_FILENAME_SZ];
#endif

    WOLFSSL_ENTER("LoadCRL");
    if (crl == NULL)
        return BAD_FUNC_ARG;

    dir = opendir(path);
    if (dir == NULL) {
        WOLFSSL_MSG("opendir path crl load failed");
        return BAD_PATH_ERROR;
    }

#ifdef WOLFSSL_SMALL_STACK
    name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (name == NULL)
        return MEMORY_E;
#endif

    while ( (entry = readdir(dir)) != NULL) {
        struct stat s;

        XMEMSET(name, 0, MAX_FILENAME_SZ);
        XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
        XSTRNCAT(name, "/", 1);
        XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);

        if (stat(name, &s) != 0) {
            WOLFSSL_MSG("stat on name failed");
            continue;
        }
        if (s.st_mode & S_IFREG) {

            if (type == SSL_FILETYPE_PEM) {
                if (XSTRSTR(entry->d_name, ".pem") == NULL) {
                    WOLFSSL_MSG("not .pem file, skipping");
                    continue;
                }
            }
            else {
                if (XSTRSTR(entry->d_name, ".der") == NULL &&
                    XSTRSTR(entry->d_name, ".crl") == NULL) {

                    WOLFSSL_MSG("not .der or .crl file, skipping");
                    continue;
                }
            }

            if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
                                                               != SSL_SUCCESS) {
                WOLFSSL_MSG("CRL file load failed, continuing");
            }
        }
    }

#ifdef WOLFSSL_SMALL_STACK
    XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    if (monitor & WOLFSSL_CRL_MONITOR) {
        word32 pathLen;
        char* pathBuf;

        WOLFSSL_MSG("monitor path requested");

        pathLen = (word32)XSTRLEN(path);
        pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR);
        if (pathBuf) {
            XSTRNCPY(pathBuf, path, pathLen);
            pathBuf[pathLen] = '\0'; /* Null Terminate */

            if (type == SSL_FILETYPE_PEM) {
                crl->monitors[0].path = pathBuf;
                crl->monitors[0].type = SSL_FILETYPE_PEM;
            } else {
                crl->monitors[1].path = pathBuf;
                crl->monitors[1].type = SSL_FILETYPE_ASN1;
            }

            if (monitor & WOLFSSL_CRL_START_MON) {
                WOLFSSL_MSG("start monitoring requested");

                ret = StartMonitorCRL(crl);
            }
        }
        else {
            ret = MEMORY_E;
        }
    }

    closedir(dir);

    return ret;
}
Esempio n. 29
0
/* Flush enough data to fill a terminal window of the given scene (used only
   by vty telnet interface). */
buffer_status_t
buffer_flush_window (struct buffer *b, int fd, int width, int height, 
		     int erase_flag, int no_more_flag)
{
  int nbytes;
  int iov_alloc;
  int iov_index;
  struct iovec *iov;
  struct iovec small_iov[3];
  char more[] = " --More-- ";
  char erase[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
		   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
		   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
  struct buffer_data *data;
  int column;

  if (!b->head)
    return BUFFER_EMPTY;

  if (height < 1)
    {
      zlog_warn("%s called with non-positive window height %d, forcing to 1",
      		__func__, height);
      height = 1;
    }
  else if (height >= 2)
    height--;
  if (width < 1)
    {
      zlog_warn("%s called with non-positive window width %d, forcing to 1",
      		__func__, width);
      width = 1;
    }

  /* For erase and more data add two to b's buffer_data count.*/
  if (b->head->next == NULL)
    {
      iov_alloc = sizeof(small_iov)/sizeof(small_iov[0]);
      iov = small_iov;
    }
  else
    {
      iov_alloc = ((height*(width+2))/b->size)+10;
      iov = XMALLOC(MTYPE_TMP, iov_alloc*sizeof(*iov));
    }
  iov_index = 0;

  /* Previously print out is performed. */
  if (erase_flag)
    {
      iov[iov_index].iov_base = erase;
      iov[iov_index].iov_len = sizeof erase;
      iov_index++;
    }

  /* Output data. */
  column = 1;  /* Column position of next character displayed. */
  for (data = b->head; data && (height > 0); data = data->next)
    {
      size_t cp;

      cp = data->sp;
      while ((cp < data->cp) && (height > 0))
        {
	  /* Calculate lines remaining and column position after displaying
	     this character. */
	  if (data->data[cp] == '\r')
	    column = 1;
	  else if ((data->data[cp] == '\n') || (column == width))
	    {
	      column = 1;
	      height--;
	    }
	  else
	    column++;
	  cp++;
        }
      iov[iov_index].iov_base = (char *)(data->data + data->sp);
      iov[iov_index++].iov_len = cp-data->sp;
      data->sp = cp;

      if (iov_index == iov_alloc)
	/* This should not ordinarily happen. */
        {
	  iov_alloc *= 2;
	  if (iov != small_iov)
	    {
	      zlog_warn("%s: growing iov array to %d; "
			"width %d, height %d, size %lu",
			__func__, iov_alloc, width, height, (u_long)b->size);
	      iov = XREALLOC(MTYPE_TMP, iov, iov_alloc*sizeof(*iov));
	    }
	  else
	    {
	      /* This should absolutely never occur. */
	      zlog_err("%s: corruption detected: iov_small overflowed; "
		       "head %p, tail %p, head->next %p",
		       __func__, b->head, b->tail, b->head->next);
	      iov = XMALLOC(MTYPE_TMP, iov_alloc*sizeof(*iov));
	      memcpy(iov, small_iov, sizeof(small_iov));
	    }
	}
    }

  /* In case of `more' display need. */
  if (b->tail && (b->tail->sp < b->tail->cp) && !no_more_flag)
    {
      iov[iov_index].iov_base = more;
      iov[iov_index].iov_len = sizeof more;
      iov_index++;
    }


#ifdef IOV_MAX
  /* IOV_MAX are normally defined in <sys/uio.h> , Posix.1g.
     example: Solaris2.6 are defined IOV_MAX size at 16.     */
  {
    struct iovec *c_iov = iov;
    nbytes = 0; /* Make sure it's initialized. */

    while (iov_index > 0)
      {
	 int iov_size;
	 
	 /*CID 12128 (#1 of 1): Out-of-bounds access (OVERRUN)
	 35. overrun-buffer-arg: Overrunning buffer pointed to by "c_iov" of 3 8-byte elements 
	 by passing it to a function which accesses it at element index 1023 (byte offset 8184)
	 using argument "iov_size" (which evaluates to 1024).*/
	 /*But this func buffer_flush_window, now we donnot use .*/
	 iov_size = ((iov_index > IOV_MAX) ? IOV_MAX : iov_index);
	 if ((nbytes = writev(fd, c_iov, iov_size)) < 0)
	   {
	     zlog_warn("%s: writev to fd %d failed: %s",
		       __func__, fd, safe_strerror(errno));
	     break;
	   }

	 /* move pointer io-vector */
	 c_iov += iov_size;
	 iov_index -= iov_size;
      }
  }
#else  /* IOV_MAX */
   if ((nbytes = writev (fd, iov, iov_index)) < 0)
     zlog_warn("%s: writev to fd %d failed: %s",
	       __func__, fd, safe_strerror(errno));
#endif /* IOV_MAX */

  /* Free printed buffer data. */
  while (b->head && (b->head->sp == b->head->cp))
    {
      struct buffer_data *del;
      if (!(b->head = (del = b->head)->next))
        b->tail = NULL;
      BUFFER_DATA_FREE(del);
    }

  if (iov != small_iov)
    XFREE (MTYPE_TMP, iov);

  return (nbytes < 0) ? BUFFER_ERROR :
  			(b->head ? BUFFER_PENDING : BUFFER_EMPTY);
}
/**
   ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
   @param in      The input buffer
   @param inlen   [in/out] The length of the input buffer and on output the amount of decoded data
   @param out     [out] A pointer to the linked list
   @return CRYPT_OK on success.
*/
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
{
   ltc_asn1_list *l;
   unsigned long err, type, len, totlen, data_offset;
   void          *realloc_tmp;

   LTC_ARGCHK(in    != NULL);
   LTC_ARGCHK(inlen != NULL);
   LTC_ARGCHK(out   != NULL);

   l = NULL;
   totlen = 0;

   if (*inlen == 0) {
      /* alloc new link */
      if ((err = _new_element(&l)) != CRYPT_OK) {
         goto error;
      }
   }

   /* scan the input and and get lengths and what not */
   while (*inlen) {
      /* read the type byte */
      type = *in;

      /* fetch length */
      len = _fetch_length(in, *inlen, &data_offset);
      if (len > *inlen) {
         err = CRYPT_INVALID_PACKET;
         goto error;
      }

      /* alloc new link */
      if ((err = _new_element(&l)) != CRYPT_OK) {
         goto error;
      }

      if ((type & 0x20) && (type != 0x30) && (type != 0x31)) {
         /* constructed, use the 'used' field to store the original identifier */
         l->used = type;
         /* treat constructed elements like SETs */
         type = 0x20;
      }
      else if ((type & 0xC0) == 0x80) {
         /* context-specific, use the 'used' field to store the original identifier */
         l->used = type;
         /* context-specific elements are treated as opaque data */
         type = 0x80;
      }

     /* now switch on type */
      switch (type) {
         case 0x01: /* BOOLEAN */
            l->type = LTC_ASN1_BOOLEAN;
            l->size = 1;
            l->data = XCALLOC(1, sizeof(int));

            if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_boolean(&len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x02: /* INTEGER */
             /* init field */
             l->type = LTC_ASN1_INTEGER;
             l->size = 1;
             if ((err = mp_init(&l->data)) != CRYPT_OK) {
                 goto error;
             }

             /* decode field */
             if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
                 goto error;
             }

             /* calc length of object */
             if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
                 goto error;
             }
             break;

         case 0x03: /* BIT */
            /* init field */
            l->type = LTC_ASN1_BIT_STRING;
            l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char.  */

            if ((l->data = XCALLOC(1, l->size)) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x04: /* OCTET */

            /* init field */
            l->type = LTC_ASN1_OCTET_STRING;
            l->size = len;

            if ((l->data = XCALLOC(1, l->size)) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x05: /* NULL */

            /* valid NULL is 0x05 0x00 */
            if (in[0] != 0x05 || in[1] != 0x00) {
               err = CRYPT_INVALID_PACKET;
               goto error;
            }

            /* simple to store ;-) */
            l->type = LTC_ASN1_NULL;
            l->data = NULL;
            l->size = 0;
            len     = 2;

            break;

         case 0x06: /* OID */

            /* init field */
            l->type = LTC_ASN1_OBJECT_IDENTIFIER;
            l->size = len;

            if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
               goto error;
            }

            /* resize it to save a bunch of mem */
            if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
               /* out of heap but this is not an error */
               break;
            }
            l->data = realloc_tmp;
            break;

         case 0x0C: /* UTF8 */

            /* init field */
            l->type = LTC_ASN1_UTF8_STRING;
            l->size = len;

            if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x13: /* PRINTABLE */

            /* init field */
            l->type = LTC_ASN1_PRINTABLE_STRING;
            l->size = len;

            if ((l->data = XCALLOC(1, l->size)) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x14: /* TELETEXT */

            /* init field */
            l->type = LTC_ASN1_TELETEX_STRING;
            l->size = len;

            if ((l->data = XCALLOC(1, l->size)) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_teletex_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_teletex_string(l->data, l->size, &len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x16: /* IA5 */

            /* init field */
            l->type = LTC_ASN1_IA5_STRING;
            l->size = len;

            if ((l->data = XCALLOC(1, l->size)) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x17: /* UTC TIME */

            /* init field */
            l->type = LTC_ASN1_UTCTIME;
            l->size = 1;

            if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            len = *inlen;
            if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
               goto error;
            }
            break;

         case 0x18:
            l->type = LTC_ASN1_GENERALIZEDTIME;
            l->size = len;

            if ((l->data = XCALLOC(1, sizeof(ltc_generalizedtime))) == NULL) {
               err = CRYPT_MEM;
               goto error;
            }

            if ((err = der_decode_generalizedtime(in, &len, l->data)) != CRYPT_OK) {
               goto error;
            }

            if ((err = der_length_generalizedtime(l->data, &len)) != CRYPT_OK) {
               goto error;
            }

            break;

         case 0x20: /* Any CONSTRUCTED element that is neither SEQUENCE nor SET */
         case 0x30: /* SEQUENCE */
         case 0x31: /* SET */

             /* init field */
             if (type == 0x20) {
                l->type = LTC_ASN1_CONSTRUCTED;
             }
             else if (type == 0x30) {
                l->type = LTC_ASN1_SEQUENCE;
             }
             else {
                l->type = LTC_ASN1_SET;
             }

             if ((l->data = XMALLOC(len)) == NULL) {
                err = CRYPT_MEM;
                goto error;
             }

             XMEMCPY(l->data, in, len);
             l->size = len;


             /* jump to the start of the data */
             in     += data_offset;
             *inlen -= data_offset;
             len = len - data_offset;

             /* Sequence elements go as child */
             if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) {
                goto error;
             }

             /* len update */
             totlen += data_offset;

             /* the flexi decoder can also do nothing, so make sure a child has been allocated */
             if (l->child) {
                /* link them up y0 */
                l->child->parent = l;
             }

             break;

         case 0x80: /* Context-specific */
             l->type = LTC_ASN1_CONTEXT_SPECIFIC;

             if ((l->data = XCALLOC(1, len - data_offset)) == NULL) {
                err = CRYPT_MEM;
                goto error;
             }

             XMEMCPY(l->data, in + data_offset, len - data_offset);
             l->size = len - data_offset;

             break;

         default:
           /* invalid byte ... this is a soft error */
           /* remove link */
           if (l->prev) {
              l       = l->prev;
              XFREE(l->next);
              l->next = NULL;
           }
           goto outside;
      }

      /* advance pointers */
      totlen  += len;
      in      += len;
      *inlen  -= len;
   }

outside:

   /* in case we processed anything */
   if (totlen) {
      /* rewind l please */
      while (l->prev != NULL || l->parent != NULL) {
         if (l->parent != NULL) {
            l = l->parent;
         } else {
            l = l->prev;
         }
      }
   }

   /* return */
   *out   = l;
   *inlen = totlen;
   return CRYPT_OK;

error:
   /* free list */
   der_sequence_free(l);

   return err;
}