~ubuntu-branches/debian/stretch/alpine/stretch

« back to all changes in this revision

Viewing changes to pith/smime.c

  • Committer: Package Import Robot
  • Author(s): Asheesh Laroia
  • Date: 2013-05-19 16:15:01 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20130519161501-epf6pfldn07xnd11
Tags: 2.10+dfsg-1
* New upstream release.
* This release ships a fix for an issue where the PREFDATETIME token
  was always set to "Sun" incorrectly. (Closes: #692870)
* This release ships a fix for IMAP-encoded non-ASCII folder names.
  (Closes: #674067)
* This release simplifies (and corrects) S/MIME handling for messages
  that encrypted *and* signed. (Closes: #653420)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1307
1307
    return(ret);
1308
1308
}
1309
1309
 
 
1310
/* 
 
1311
 * Encrypt file; given a path (char *) fp, replace the file
 
1312
 * by an encrypted version of it. If (char *) text is not null, then
 
1313
 * replace the text of (char *) fp by the encrypted version of (char *) text.
 
1314
 */
 
1315
int
 
1316
encrypt_file(char *fp, char *text)
 
1317
{
 
1318
  const EVP_CIPHER *cipher = NULL;
 
1319
  STACK_OF(X509) *encerts = NULL;
 
1320
  X509 *cert;
 
1321
  PERSONAL_CERT  *pcert;
 
1322
  BIO *in;
 
1323
  PKCS7 *p7 = NULL;
 
1324
  FILE *fpp;
 
1325
  int rv = 0;
 
1326
 
 
1327
  smime_init();
 
1328
  if((pcert = ps_global->smime->personal_certs) == NULL)
 
1329
    return 0;
 
1330
 
 
1331
  cipher = EVP_aes_256_cbc();
 
1332
  encerts = sk_X509_new_null();
 
1333
  
 
1334
  if((cert = get_cert_for(pcert->name)) != NULL)
 
1335
     sk_X509_push(encerts, cert);
 
1336
  else
 
1337
     goto end;
 
1338
 
 
1339
  if(text){
 
1340
    in = BIO_new(BIO_s_mem());
 
1341
    if(in == NULL)
 
1342
      goto end;
 
1343
    (void) BIO_reset(in);
 
1344
    BIO_puts(in, text);
 
1345
  }
 
1346
  else{
 
1347
    if(!(in = BIO_new_file(fp, "rb")))
 
1348
      goto end;
 
1349
 
 
1350
    BIO_read_filename(in, fp);
 
1351
  }
 
1352
 
 
1353
  if((p7 = PKCS7_encrypt(encerts, in, cipher, 0)) == NULL)
 
1354
     goto end;
 
1355
  BIO_set_close(in, BIO_CLOSE);
 
1356
  BIO_free(in);
 
1357
  if(!(in = BIO_new_file(fp, "w")))
 
1358
    goto end;
 
1359
  BIO_reset(in);
 
1360
  rv = PEM_write_bio_PKCS7(in, p7);
 
1361
  BIO_flush(in);
 
1362
 
 
1363
end:
 
1364
  BIO_free(in);
 
1365
  PKCS7_free(p7);
 
1366
  sk_X509_pop_free(encerts, X509_free);
 
1367
 
 
1368
  return rv;
 
1369
}
1310
1370
 
1311
1371
/*
1312
1372
 * Encrypt a message on the way out. Called from call_mailer in send.c
1722
1782
    return x;
1723
1783
}
1724
1784
 
 
1785
/* decrypt an encrypted file.
 
1786
   Args: fp - the path to the encrypted file.
 
1787
         rv - a code that thells the caller what happened inside the function 
 
1788
   Returns the decoded text allocated in a char *, whose memory must be
 
1789
   freed by caller 
 
1790
 */
 
1791
 
 
1792
char *
 
1793
decrypt_file(char *fp, int *rv)
 
1794
{
 
1795
  PKCS7 *p7 = NULL;
 
1796
  char *text, *tmp;
 
1797
  BIO *in = NULL, *out = NULL;
 
1798
  EVP_PKEY *pkey = NULL, *key = NULL;
 
1799
  PERSONAL_CERT *pcert = NULL;
 
1800
  X509 *recip, *cert;
 
1801
  STORE_S *outs = NULL, *store, *ins;
 
1802
  int i, j;
 
1803
  long unsigned int len;
 
1804
  void *ret;
 
1805
 
 
1806
  smime_init();
 
1807
 
 
1808
  if((text = read_file(fp, 0)) == NULL)
 
1809
    return NULL;
 
1810
 
 
1811
  tmp = fs_get(strlen(text) + (strlen(text) << 6) + 1);
 
1812
  for(j = 0, i = strlen("-----BEGIN PKCS7-----") + 1; text[i] != '\0' 
 
1813
                && text[i] != '-'; j++, i++)
 
1814
     tmp[j] = text[i];
 
1815
  tmp[j] = '\0';
 
1816
 
 
1817
  ret = rfc822_base64(tmp, strlen(tmp), &len);
 
1818
 
 
1819
  if((in = BIO_new_mem_buf((char *)ret, len)) != NULL){
 
1820
     p7 = d2i_PKCS7_bio(in, NULL);
 
1821
     BIO_free(in);
 
1822
  }
 
1823
 
 
1824
  if(text) fs_give((void **)&text);
 
1825
  if(ret) fs_give((void **)&ret);
 
1826
 
 
1827
  if((pcert = ps_global->smime->personal_certs) == NULL)
 
1828
   goto end;
 
1829
 
 
1830
  if((i = load_private_key(pcert)) == 0
 
1831
     && ps_global->smime
 
1832
     && ps_global->smime->need_passphrase
 
1833
     && !ps_global->smime->already_auto_asked)
 
1834
        for(; i == 0;){
 
1835
           ps_global->smime->already_auto_asked = 1;
 
1836
           if(pith_opt_smime_get_passphrase){
 
1837
             switch((*pith_opt_smime_get_passphrase)()){
 
1838
                case 0 : i = load_private_key(pcert);
 
1839
                         break;
 
1840
 
 
1841
                case 1 : i = -1;
 
1842
                         break;
 
1843
 
 
1844
                default: break; /* repeat until we cancel */
 
1845
             }
 
1846
           }
 
1847
           else
 
1848
              i = -2;
 
1849
        }
 
1850
 
 
1851
  if(rv) *rv = i;
 
1852
 
 
1853
  if((key = pcert->key) == NULL)
 
1854
    goto end;
 
1855
 
 
1856
  recip = get_cert_for(pcert->name);
 
1857
  out = BIO_new(BIO_s_mem());
 
1858
  (void) BIO_reset(out);
 
1859
 
 
1860
  i = PKCS7_decrypt(p7, key, recip, out, 0);
 
1861
 
 
1862
  if(F_OFF(F_REMEMBER_SMIME_PASSPHRASE,ps_global))
 
1863
     forget_private_keys();
 
1864
 
 
1865
  if(i == 0){
 
1866
    q_status_message1(SM_ORDER, 1, 1, _("Error decrypting: %s"),
 
1867
                              (char*) openssl_error_string());
 
1868
    goto end;
 
1869
  }
 
1870
 
 
1871
  BIO_get_mem_data(out, &tmp);
 
1872
 
 
1873
  text = cpystr(tmp);
 
1874
  BIO_free(out);
 
1875
 
 
1876
end:
 
1877
  PKCS7_free(p7);
 
1878
 
 
1879
  return text;
 
1880
}
1725
1881
 
1726
1882
/*
1727
1883
 * Try to decode (decrypt or verify a signature) a PKCS7 body
1738
1894
    PERSONAL_CERT       *pcert = NULL;
1739
1895
    char    *what_we_did = "";
1740
1896
    char     null[1];
1741
 
    char     newSec[100];
1742
1897
 
1743
1898
    dprint((9, "do_decoding(msgno=%ld type=%d subtype=%s section=%s)", msgno, b->type, b->subtype ? b->subtype : "NULL", (section && *section) ? section : (section != NULL) ? "Top" : "NULL"));
1744
1899
    null[0] = '\0';
1753
1908
    }
1754
1909
    else{
1755
1910
 
1756
 
        snprintf(newSec, sizeof(newSec), "%s%s1", section ? section : "", (section && *section) ? "." : "");
1757
 
        p7 = get_pkcs7_from_part(msgno, newSec);
 
1911
        p7 = get_pkcs7_from_part(msgno, section && *section ? section : "1");
1758
1912
        if(!p7){
1759
1913
            q_status_message1(SM_ORDER, 2, 2, "Couldn't load PKCS7 object: %s",
1760
1914
                             (char*) openssl_error_string());