# Upgrade to 8.3.1 from 8.0.3 breaks crypto lib call

**URL:** <https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507>\
**Category:** General\
**Created:** [June 13, 2020, 8:43am UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507 "2020-06-13T08:43:55Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![anniepoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/anniepoo/32/12_2.png) [@anniepoo](https://swi-prolog.discourse.group/u/anniepoo)\
**Post date:** [June 13, 2020, 8:43am UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/1 "2020-06-13T08:43:55Z")

</div>

Upgrade to 8.3.1 from 8.0.3

```
%! make_login_cookie(+UName:atom, -Cookie:string) is semidet
%
% Make the contents (a string of hex) of a persistent login cookie
% using:
%
% * the passed in user name
% * the rememberme_duration
% * a secret generated and stored in file
make_login_cookie(UName, Cookie) :-
      www_form_encode(URLEncodedUName, UName),
      get_time(Now),
      setting(identity:rememberme_duration, DurSecs),
      Expires is floor(Now + DurSecs),
      get_crypto_key(Key),
      atomics_to_string([URLEncodedUName, "/", Expires], PlainText),
      crypto_n_random_bytes(12, Nonce),
      % next line throws
      crypto_data_encrypt(PlainText, 'chacha20-poly1305',
                          Key, Nonce, CipherText, []),
      string_codes(CipherText, CipherTextCodes),
      append(Nonce, CipherTextCodes, TokenList),
      hex_bytes(Cookie, TokenList).

 crypto:'_crypto_data_encrypt'/8: Domain error: `cipher' expected, found `'chacha20-poly1305''

```

I presume the correct thing to pass is in the foreign library crypto4pl, but I’m reluctant to select randomly, as this has security implications.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 13, 2020, 9:13am UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/2 "2020-06-13T09:13:04Z")

</div>

Works fine here (Ubuntu 20.04. Note that you need to have compiled against a version of OpenSSL that supports this algorithm. That probably requires the right OpenSSL version (range) and possibly the right flags.

---

<div class="post-metadata">

**Author:** ![anniepoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/anniepoo/32/12_2.png) [@anniepoo](https://swi-prolog.discourse.group/u/anniepoo)\
**Post date:** [June 13, 2020, 10:39am UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/3 "2020-06-13T10:39:54Z")

</div>

on 18.04

Odd part is that I installed 8.0.3 on same machine. Maybe I upgraded the openssl lib?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 13, 2020, 1:09pm UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/4 "2020-06-13T13:09:38Z")

</div>

I don’t know. I did a quick grep for `chacha` on the source and only found hits in the comments so I suspect crypto\_data\_encrypt/6 simply passes strings to OpenSSL to select he algorithm. Most likely the `openssl` command has some option to check which algorithms it supports. Make sure Prolog and `openssl` bind to the same library though. An old library or header in the wrong place is another common cause for issues like this.

---

<div class="post-metadata">

**Author:** ![stuz5000](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stuz5000/32/940_2.png) [@stuz5000](https://swi-prolog.discourse.group/u/stuz5000)\
**Post date:** [June 18, 2020, 5:53am UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/5 "2020-06-18T05:53:21Z")

</div>

I recently upgraded from 8.0.3 to 8.2.0 and I’m having problems with strings in the FFI (also fails in 8.0.3). The following hits an assert:

```prolog
flags = PL_STRING | REP_UTF8
PL_put_chars(swipl_goalCharList, flags, -1, query.encode("utf-8"))

```

```prolog
from pyswip.core import PL_open_foreign_frame, PL_new_term_refs, \
    PL_initialise, \
    PL_new_term_ref, PL_chars_to_term, PL_call, PL_discard_foreign_frame, PL_put_list_chars, \
    PL_put_chars, REP_UTF8, PL_STRING, REP_MB, REP_ISO_LATIN_1

def _initialize():
    """
    MUST NOT be called twice.
    """
    args = []
    args.append("./")
    result = PL_initialise(len(args), args)
    if not result:
        raise Exception("Could not initialize the Prolog environment."
                          "PL_initialise returned %d" % result)

    swipl_fid = PL_open_foreign_frame()
    swipl_load = PL_new_term_ref()
    PL_chars_to_term("asserta(pyrun(GoalString,BindingList) :- "
                     "(atom_chars(Chars__,GoalString),"
                     "atom_to_term(Chars__,Goal_,BindingList),"
                     "expand_goal(Goal_,Goal__),"
                     "call(Goal__))).", swipl_load)
    PL_call(swipl_load, None)
    PL_discard_foreign_frame(swipl_fid)

_initialize()

query = 'assertz(father(michael,john)).'

swipl_fid = PL_open_foreign_frame()
swipl_args = PL_new_term_refs(2)
swipl_goalCharList = swipl_args
swipl_bindingList = swipl_args + 1

# PL_put_list_chars(swipl_goalCharList, query) # Success!

flags = PL_STRING | REP_UTF8 # --> 0x100005
print("{:0x}".format(flags & ~(REP_UTF8|REP_MB|REP_ISO_LATIN_1))) # --> 5
PL_put_chars(swipl_goalCharList, flags, -1, query.encode("utf-8"))
#PL_put_chars(swipl_goalCharList, PL_STRING | REP_UTF8, -1, query.encode("utf-8")) # same failure

```

Fails with

```prolog
PL_put_chars: Assertion failed: 0
C-stack trace labeled "assert_fail":
  [0] PL_strtod() at ??:? [0x7fea032a83c8]
  [1] __assert_fail() at ??:? [0x7fea03265de7]
  [2] PL_put_chars() at ??:? [0x7fea031c4089]
  [3] ffi_call_unix64() at ??:? [0x7fe9e8466dae]
  [4] ffi_call() at ??:? [0x7fe9e846671f]
  [5] _ctypes_callproc() at ??:? [0x7fe9e867a944]
  [6] _ctypes_callproc() at ??:? [0x7fe9e867b0d4]
  [7] /home/sir/venv/p37_default/bin/python(_PyObject_FastCallKeywords+0x4eb) [0x5d96db]
  [8] /home/sir/venv/p37_default/bin/python(_PyEval_EvalFrameDefault+0x4679) [0x551e89]
  [9] 

```

PL\_put\_chars is implented as:

```prolog
nt
PL_put_chars(term_t t, int flags, size_t len, const char *s)
{ GET_LD
  PL_chars_t text;
  word w = 0;
  int rc = FALSE;

  if ( len == (size_t)-1 )
    len = strlen(s);

  text.text.t = (char*)s;
  text.encoding = ((flags&REP_UTF8) ? ENC_UTF8 : \
		    (flags&REP_MB) ? ENC_ANSI : ENC_ISO_LATIN_1);
  text.length = len;
  text.canonical = FALSE;
  text.storage = PL_CHARS_HEAP;

  flags &= ~(REP_UTF8|REP_MB|REP_ISO_LATIN_1);

  if ( flags == PL_ATOM )
    w = textToAtom(&text);
  else if ( flags == PL_STRING )
    w = textToString(&text);
  else if ( flags == PL_CODE_LIST || flags == PL_CHAR_LIST )
  { PL_put_variable(t);
    rc = PL_unify_text(t, 0, &text, flags);
  } else
    assert(0);

  if ( w )
  { setHandle(t, w);
    rc = TRUE;
  }

  PL_free_text(&text);

  return rc;
}

```

I don’t see a reason why it would hit the assert.

I don’t see a way to revert to 8.0.3 to test anything. There is no package in ppa stable branch:

> **[SWI-Prolog stable : “SWI Prolog” team](https://launchpad.net/~swi-prolog/+archive/ubuntu/stable)**
>
> Comprehensive Prolog implementation with extensive libraries and development tools. Primarily targetted at teaching, RDF processing and web-related tasks, such as creating web services or analysing web content.

  
Did it get deleted? (I’d need bionic / Ubuntu 18).

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 18, 2020, 11:34am UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/6 "2020-06-18T11:34:01Z")

</div>

The pyswipl FFI uses hard coded constants that are copied from `SWI-Prolog.h`. A number of these values have changed. This is a very rare situation, but was necessary to accommodate rational numbers.

The best route is probably to resync these constants in the Python interface. Ideally such an upgrade would also support the new SWI-Prolog rational numbers …

---

<div class="post-metadata">

**Author:** ![stuz5000](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stuz5000/32/940_2.png) [@stuz5000](https://swi-prolog.discourse.group/u/stuz5000)\
**Post date:** [June 18, 2020, 6:30pm UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/7 "2020-06-18T18:30:18Z")

</div>

Ooof. PL\_STRING changed from 5 to 6.  
I also found REP\_UTF8 was incorrect in pyswip (I don’t think it has changed in SWI for some time).  
Thank @jan . This saved me a lot of hunting.

This could have used a major version number increment since its a breaking API change.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 18, 2020, 7:09pm UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/8 "2020-06-18T19:09:05Z")

</div>

> [@stuz5000](#):
>
> This could have used a major version number increment since its a breaking API change.

We went from 8.0 to 8.2, which in SWI-Prolog’s versioning is a new release cycle. The project is less suitable for the common major.minor.patch semantics. On the stable release we want to maintain the patch level semantics. On the development cycle things just develop and may break. As is, major releases are landmarks that indicate major changes of functionality. I agree this is all a bit fuzzy ☹

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 18, 2020, 7:45pm UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/9 "2020-06-18T19:45:46Z")

</div>

> [@stuz5000](#):
>
> Ooof. PL\_STRING changed from 5 to 6.  
> I also found REP\_UTF8 was incorrect in pyswip

Will you make a PR on pyswip?

---

<div class="post-metadata">

**Author:** ![stuz5000](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/stuz5000/32/940_2.png) [@stuz5000](https://swi-prolog.discourse.group/u/stuz5000)\
**Post date:** [June 19, 2020, 8:47pm UTC](https://swi-prolog.discourse.group/t/upgrade-to-8-3-1-from-8-0-3-breaks-crypto-lib-call/2507/10 "2020-06-19T20:47:44Z")

</div>

Yes – it is already done and accepted.
